Ruby 关于 Proc 与 return 的一个疑问

cikey · 2016年08月11日 · 最后由 chcyellow 回复于 2016年08月14日 · 2166 次阅读

看了几篇关于 Proc、block 和 lambda 的文章,有一个疑问如下:

先来一段代码:

def f0()
  p = Proc.new { return 0 }
  p.call
  1
end

def f1(p)
  p.call
  1
end

def f2()
  Proc.new { return 0 }
end

puts f0()  # 返回0
puts f1(f2())  # 报LocalJumpError: unexpected return


def f3()
  yield(11)
end

puts f3(){|x| return x}  # 报LocalJumpError: unexpected return

关于这段的疑问是:不清楚f0不会报错,但是f1(f2())报错的根本原因。

个人感觉是这样—— f1p.call的时候是回到f2的上下文去执行的。 f2的上下文还在,这样f1执行到p.call的话就相当于直接在方法外f2().call

yield也是,相当于直接在f3(){|x| return x}这个位置的上下文 return,也是在方法外

return是方法执行后 return value 给调用方,如果在方法外 return 就没有意义

不知道这样理解对不对

1楼 已删除

f1(f2()) 是因为 proc 和 lambda 的一些区别:lambda 直接从 block 返回,而 proc 直接从定义 proc 的作用域返回了,就是说从 def f2() ...... end 这个方法定义返回了,因为你 f1(f2()) 调用的时候,f2 的方法定义作用域早就已经没有了,所以 ruby 也不知道要从哪返回了,所以 LocalJumpError ;

f3(){|x| return x} 同理;

#1 楼 @chcyellow HelloWorld 是类,也是对象啊(类对象)。bob.name 这是一个方法调用,不是直接访问实例变量。对象在类内部是可以访问实例变量的,在类外部就需要存在属性读写方法了(如果不用上下文探针打破封装的话)。

#2 楼 @yeshuai 原来是这样。THX!

#4 楼 @cikey 研读下《Ruby 元编程 (第 2 版)》

谢谢。今天看代码的未来中他说 Ruby 中类也是对象,才理解。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册