Day 19 Ruby Proc vs Lambda

物件

介绍 Proc 跟 Lambda 前先来介绍一下 Ruby 的物件。
在 Ruby 里几乎所有东西都是物件,只有 block、method 以及 if else 不是物件。

block

  • 没办法单独存活,但可寄生在别的方法後面
  • 是一段不会被主动执行的程序码
  • 会自动回传最後一行的执行结果

block 有两种型态:

  1. do end
    结合率较弱,有多行通常会用 do end
  2. {}
    结合率较强,只有一行通常会用{}

yield

用来执行 block 内的程序码。

范例:

def say_hello
  puts "Hello, 你好"
yield
  puts "Hello, ⼤家好"
end
say_hello {
  puts "here!"
}
puts "there!"

以上范例将 {} 寄生在 say_hello 方法後面,并搭配 yeild 执行 block 内的程序码,会先後印出:
Hello, 你好 (跳过前4行,执行 say_hello 方法)
here! (yield 转移控制权到下面的 block)
Hello, ⼤家好 (yield 转移控制权回到上面的 block)
there! (跳出 say_hello 方法,执行外层的 puts "there!")

Proc vs Lambda

相同点:

其中 Proc 跟 Lambda 都是可以让 block 物件化的方法,让 block 能单独存在,变成可被呼叫的物件。
加入 Proc 或 Lambda 後就可以用 call 来呼叫他了。

范例:

a = Proc.new {|n| n * 2 }
a = -> (n) { n + 2 }
p a.call(2)

范例第一行是使用 Proc 的写法,
第二行是使用 Lambda 的写法,
两者都会印出 4,可以择一使用。

两个差异点:

  1. Lambda 会检查代入的引数(Argument)数量,但 Proc 不会。
    当使用 Lambda 且引数数量有错时,错误讯息会跟你说,使用 Proc 时则不会告诉你。

Proc 范例1:

a = Proc.new {|n| n * 2 }
p a.call()

如果引数个数小於参数会印出 NoMethodError

Proc 范例2:

a = Proc.new {|n| n * 2 }
p a.call(2,3)

如果引数个数大於参数会正常印出 4

Lambda 范例1:

a = -> (n) { n + 2 }
p a.call()

如果引数个数小於参数会印出 wrong number of arguments (given 0, expected 1) (ArgumentError)

Lambda 范例2:

a = -> (n) { n + 2 }
p a.call(2,3)

如果引数个数大於参数会印出 wrong number of arguments (given 2, expected 1) (ArgumentError)

  1. 如果在 Proc 的 block 内加入 return 会立即跳出,不会执行里面的程序码,而在 Lambda 的 block 内加入 return 会转移控制权给 block,继续执行里面的程序码。

范例:

a = Proc.new { return 2 }
p a.call()

当 Proc 遇到 return 时会跳出,不会执行 block 内的程序。

a = lambda { return 2 }
p a.call()

当 lambda 遇到 return 时不会跳出,可以印出 2。

参考:
[1]What's the difference between a proc and a lambda in Ruby?


<<:  [C 语言笔记--Day22] warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]

>>:  Youtube Analytics API 教学 - 基本架构 reports.query

DAY22-EXCEL统计分析:双因子变异数分析介绍

双因子变异数分析 双因子变异数分析主要是想知道两个因子之间是否有明显的交互作用或主效果。因此双因子变...

EP 27: MockData come back with UI design in TopStore App

Hello, 各位 iT邦帮忙 的粉丝们大家好~~~ 本篇是 Re: 从零开始用 Xamarin 技...

1. 新Leader不该事必躬亲

前言 这篇适合给first time leader,特别是刚被promote成team leade...

Day8 Function and Interface

Function func (basedMethod) funcName(parameters)(r...

Chapter3 今天来学习画一棵树(I)学学人家DOM 自己用递回做一个树状图结构

你是说...树吗? 嘿~丢!铁人赛至今已经过半,实在是油尽灯枯,想不到主题了,刚好看到这两个很赞的树...