Difference between lambda and -> operator in Ruby

2019-01-26 10:53发布

The following two scopes generate the same result, which syntax is preferable and is there any other difference?

scope :paid, lambda { |state| where(state: state) }

scope :paid, ->(state) { where(state: state) }

3条回答
放我归山
2楼-- · 2019-01-26 11:18

-> is literal syntax, like ". Its meaning is fixed by the language specification.

Kernel#lambda is a method just like any other method. It can be overridden, removed, overwritten, monkeypatched, intercepted, …

So, semantically, they are very different.

It is also possible that their performance is different. Kernel#lambda will at least have the overhead of a method call. The fact that the execution engine cannot actually know what Kernel#lambda does at runtime (since it could be monkeypatched) would also preclude any static optimizations, although I don't believe any existing Ruby execution engine statically optimizes lambda literals in any meaningful way.

查看更多
时光不老,我们不散
3楼-- · 2019-01-26 11:28

It's preferable, due to readibility reasons, to use new syntax -> (introduced in Ruby 1.9) for single-line blocks and lambda for multi-line blocks. Example:

# single-line
l = ->(a, b) { a + b }
l.call(1, 2)

# multi-line
l = lambda do |a, b|
  tmp = a * 3
  tmp * b / 2
end
l.call(1, 2)

It seems a community convention established in bbatsov/ruby-style-guide.

So, in your case, would be better:

scope :paid, ->(state) { where(state: state) }
查看更多
我想做一个坏孩纸
4楼-- · 2019-01-26 11:40

There is no difference, both returns the same Proc object:

irb(main):033:0> lambda {|x| x*x}
=> #<Proc:0x007ff525b55b90@(irb):33 (lambda)>
irb(main):034:0> ->(x) {x*x}
=> #<Proc:0x007ff525b7e068@(irb):34 (lambda)>

In my opinion, -> is more readable.

查看更多
登录 后发表回答