tags:

views:

95

answers:

2

I often prefer to do this:

a, b = lambda do |data|
    [f1(data), f2(data)]
end.call(some_function(some_data))

instead of this:

data = some_function(some_data))
a, b = f1(data), f2(data)

or this:

a, b = f1(some_function(some_data)), f2(some_function(some_data))

Is there any negative consequence from using lambdas for almost every single thing?

+7  A: 

The principal consequence is Ruby programmers aren't particularly accustomed to doing it this way. Either one of your alternatives would be more easily readable by members of the community, other members of your team, future maintainers, etc.

The secondary consequence is creating one-off lambda functions in this way will be slower than calling static functions. Creating lambdas aren't extraordinarily slow by any means, but it's still slower than not using them. If you did this a lot, it would start to add up. To give some context, creating an empty lambda takes about 10 times longer to create than an empty array. So if you were doing this repeatedly (e.g. inside a function call that gets used over and over), that difference could add up.

Lastly, there is at least one other way to do it. I'm sure some others exist, too...

a, b = [:f1, :f2].collect { |fn| send(fn, some_function(some_data)) }

All in all, though, I think your first alternative is the cleanest approach:

data = some_function(some_data))
a, b = f1(data), f2(data)

It's entirely clear what you're doing and is also efficient.

wuputah
Alas, I removed my `Object#tap` idea since tap always returns what was tapped, not the result from the block.
wuputah
I agree with this entirely. I'd turn the original question around and ask when the indirection of creating lambdas *does* make sense. I'm not the best person to answer that, but my most common use of lambdas is to create them dynamically in outer loops for calling in inner loops. The main motivator is performance, but it can also actually help code clarity by putting decisions at the place where they logically happen (e.g., what comparison function am I about to apply to these 50000 things) rather than in the bowels of an iteration.
glenn mcdonald
+3  A: 

I can't comment yet so I'm just going to mirror Wuputah, he's right. Every single Ruby optimization video I've watched and every book I've read has said to avoid lambdas unless you absolutely need them because they can be huge performance hits when you try to scale your app. This isn't to say you shouldn't use them, just don't abuse them.

FannyPack
Can you provide a link? Thank you.
Erik Escobedo
I can try. These are two videos I have bookmarked under optimization. There's another one I can't find that benchmarks Rubinius and he goes over some ways to speed up your code and he covers lambdas: http://vimeo.com/12705404 http://pivotallabs.com/talks/57-writing-fast-ruby-learning-from-merb-and-rails-3
FannyPack
Here's another video that points out that Lambda's are a huge performance hit: http://envycasts.com/products/scaling-ruby. It's not free though and I'm not sure it was worth the $9. I did learn some things but not $9 worth; more like $1.50 worth. A more reasonable price-to-value ratio would be at $5 a video.
FannyPack