23 ms·
That may accomplish the same thing, but the direct translation would be: if baz > 10 func = method(:foo) else func = method(:bar) end
by sandal 16y ago
That may accomplish the same thing, but the direct translation would be:
if baz > 10
func = method(:foo)
else
func = method(:bar)
end
result = func.call
Here, we actually deal with the Method objects, rather than just sending a dynamic message. Although the send() approach would be closer to idiomatic Ruby, I wanted to emphasize that dealing with methods as first class objects in Ruby is indeed possible.
- mcantor 16y agoI HATE dealing with first class functions in Ruby. I understand that it was a design choice, but man, in Python you can pass a function or a lambda and you just don't have to worry about which one you're calling. In Ruby, () will explode on a Proc object. What is with that?!!?
- epochwolf 16y agoYou can call a proc with [] p = Proc.new {|str| puts "Hello #{str}" } p["World"] # prints "Hello World" :)
- mcantor 16y agoI'm aware of this, but it's still not (). You still must be aware that you are dealing with an unbound proc object, and it must be handled differently than usual!
- Twisol 16y agoBecause () doesn't call a method, it's simply used where a method call occurs. To call a callable object, you use #call or (as mentioned by epochwolf) #[], the latter of which I personally detest. It's fun to contrast this with Lua, by the way.
- aarongough 16y agoLua is a great little language... I only really 'discovered' it a few weeks ago and have really enjoyed what I've seen so far. I don't think it will replace Ruby for me, but I like it's minimal feel for comparison...
- mcantor 16y agoIt's the inconsistency that bothers me. In Python, you can make anything callable by providing a __call__() method, and the parentheses will work as expected. This makes functions fungible with anything, including any object or anonymous function. In Ruby, only methods are callable, and everything else must be called with the call() method, which means you can't use one in a place where the other might be expected. They're two concepts with the same verb--call--that require different syntax. It's inconsistent.
- Confusion 16y agoYou can also make anything callable in Ruby: just provide a call method. The parenthesis will still work as may be expected in Ruby, but, as several folks said before: in Ruby parenthesis are not used to call anything. A method is called simply be mentioning it. Anything that follows is an argument and sometimes parameters are needed for disambiguation of the parameters. This is counterintuitive, only because it differs from most other languages. If you want to postpone evaluation, you have to wrap the method call in a closure that you .call later: in Ruby a method is not a closure and not a function pointer. It's different than in many other languages, but that alone doesn't make it inconsistent.
- mcantor 16y agoThank you--this is a good explanation of why the parentheses don't work on anonymous functions: Ruby's immediate calling essentially forces you to choose between "objects that you can call like methods" and "objects that you can easily pass around." This hearkens back to carbon8's comment (http://news.ycombinator.com/item?id=1141245 http://news.ycombinator.com/item?id=1141245); viewing Ruby's handling of first-class functions as "inconsistent" definitely betrays a Python-centric view of things. In that sense, I see why it's not so bad; the difference between methods and anonymous functions is very explicit, and when you want to pass things around, it's likely that you will have target code which expects a Proc object and source code that generates it. Perhaps it's not so bad because there are few legitimate use cases, if any, for transporting a method when an arbitrary block is expected.
- carbon8 16y ago
- carbon8 16y agoAre you actually passing around methods in Ruby and, if so, why? As I've pointing out in the past (http://news.ycombinator.com/item?id=1141245 http://news.ycombinator.com/item?id=1141245), passing around methods is very rare in Ruby due to the flexibility of Procs.
- mcantor 16y agoInteresting! I am a half-breed; I write Python at my day job and Ruby in my personal projects. You seem to be suggesting that I am sort of making a mountain out of a molehill. Can you perhaps elaborate on this? I have definitely felt this pain before; I'm not just complaining about it because I "like the Python way more." But if I'm not using Ruby "as intended," I would like to know how I should be using it instead! I feel like the "Python way" is powerful because you don't have to think about whether you're dealing with an anonymous function or a function, whereas in Ruby you must know for sure which one you are dealing with, because they are invoked differently. I'm interested to know how it isn't really a problem, if that's how you feel.
- carbon8 16y agoIt's not a problem in Ruby because you don't pass around method instances, you pass around Procs (wrapped blocks, lambdas and procs), so if you are passing a callable around, you know it's a Proc. If you are passing around a method instance, you should almost certainly be using a block, lambda or proc. Also, see wycats post: http://yehudakatz.com/2010/02/21/ruby-is-not-a-callable-oriented-language/ http://yehudakatz.com/2010/02/21/ruby-is-not-a-callable-orie...
- yxhuvud 16y agoIf you have a method that in python would take a function as a parameter then it usually will be passed as a block in ruby. This doesn't really work if you would want to pass several procs into a method, but honestly, that is not very common.
- sandal 16y agoWell, a Method object and a Proc are two different things, but somewhat similar, so it still makes sense to discuss Proc behavior here. I would like it if this worked: a = lambda { |x| x + 1 } a(3) #=> 4 But since it doesn't, the alternatives are not too bad (though likely far too numerous for Python tastes) a[3] #=> 4 a.(3) #=> 4 (on Ruby 1.9) I think that Ruby's ability to call methods without () make for better readability in the case of writing domain specific interfaces, but come at a cost in other places. Personally I think it's a worthwhile tradeoff but I can see the other side of the argument.
- ataggart 16y agoThis discussion really makes me appreciate clojure.
- rue 16y agoWhy is that?