08Jun

Ruby, Python, and references to functions…

Posted by Elf Sternberg as programming, python, ruby, Uncategorized

I know there are people out there who love the way Ruby does some things, but there’s one feature of Ruby that drives me nuts, mostly because it doesn’t do things The One True Way of Python. And that’s call by reference.

In Python, everything is a reference. Let’s say you have some methods, and you need to know which one to call. This makes processor case statements easy:

def whichparam(parameter):
    def foo:
        pass

    def bar:
        pass

    def baz:
        pass

    return { 'withone': foo,
             'withtwo': bar,
             'withyou': baz }.get(parameter, baz)()

This case statement will, based on the parameter passed in, execute the function and bubble the value back up to the return statement. This is an incredibly useful technique when you have a finite number of switchable formats or rendering tools that you want to invoke based on user input. More advanced techniques using closure and the automatic generation of function objects is also possible, but not the scope of this post.

It seems to me that, although it’s supposedly at the core of Ruby’s thinking, the whole proc and .call() syntax looks tacked on to the end. It’s messy and inelegant and definitely needs something better. So far, compared to the incredible power of Python closures and its flat variable namespace, Ruby isn’t winning me over.

Am I just missing something? Is there some special Ruby sauce for doing what seems to come so naturally in Python? Admittedly, the lack of anonymous functions in Python is something that also annoys me, but not as much; the whitespace-as-delimiter actually makes that tolerable because it makes defining the name short and sweet.

3 Responses to Ruby, Python, and references to functions…

dstar

June 8th, 2008 at 1:54 pm

Are you looking for something like
class MyClass
def foo
end
def bar
end
def baz
end
def whichparam(parameter)
if param=’quux’
return self.send(:foo,parameter)
…..
end

Elf Sternberg

June 8th, 2008 at 2:55 pm

To some extent, but I’d also like to know how to do it in within the current namespace, as you can with nested functions within a method in Python, and it’s the case statement’s power. You’ve described the invocation, which is fine; how do I get the reference?

I think that Ruby’s “You don’t need parentheses to trigger a method” has poisoned Ruby’s headaround.

dstar

June 8th, 2008 at 5:39 pm

The reference to e.g. foo()? Object#send takes a Symbol or a String; you don’t have to do anything special.

I’m not sure I’m answering the right question, though, as I don’t really understand the python code. Are blocks maybe a better answer to what you’re looking for?

def bar (baz, &quux)
puts baz
yeild baz
end

bar(“Weeble”) { |wobble| puts “#{wobble} falls down”}

=> “Weeble\nWeeble falls down\n”

Comment Form

Subscribe to Feed

Categories

Calendar

June 2008
M T W T F S S
« May   Jul »
 1
2345678
9101112131415
16171819202122
23242526272829
30