关闭如何为Ruby的define_singleton_method工作?
这个
Ruby(2.2.3p173)代码:
class A def msg "hello" end def p Proc.new { msg } end def lam lambda { msg } end def blk (1..3).map { msg }.join(" and ") end def d1(obj) obj.define_singleton_method(:say1) { msg } end def d2(obj) bound = msg # <== Why is this needed? obj.define_singleton_method(:say2) { bound } end end a = A.new puts a.p.call puts a.lam.call puts a.blk obj = Object.new a.d1(obj) begin # Why does this fail? puts obj.say1 rescue puts "caught: #{$!}" end a.d2(obj) puts obj.say2 产生这个输出: hello hello hello and hello and hello caught: undefined local variable or method `msg' for #<Object:0x00000001a20638> hello 是什么让d1和d2有所不同?为什么所有的块都会看到msg,除了传递给define_singleton_method的块? 更新: 我认为归结为:
我在这里找到的:Of closures,methods,procs,scope,and Ruby. 具有{msg}的所有这些各种块必须像Proc主体那样工作. define_singleton_method正在获取块并为其提供方法规则. 解决方法
答案与自我和范围有关
在ruby中创建新范围有三种方法. 您的类创建一个范围,并且您的每个方法都创建一个包含特定于它们的绑定的范围.闭包很特别.当您定义块时,闭包将捕获周围的绑定,并且块结束后块特定绑定将消失.例如: def my_method #Method scope x = "Goodbye" yield("Cruel") end x = "Hello" #Closure says "I am going to grab the local bindings from my scope my_method {|y| "#{x},#{y} world" } 什么时候编写代码 obj.define_singleton_method(:say1) { msg } 闭包抓取的唯一本地绑定是’obj’ def d2(obj) puts "in the scope of method :d2,I have acces to the :msg method: #{methods.include?(:msg)}" puts "---" obj.define_singleton_method(:say2) do puts "in the scope of this closure,I have acces to the :msg method: #{methods.include?(:msg)}" puts "Things I do have access to: " puts methods puts local_variables end end 一个关于ruby最重要部分的简单打印声明,self,将向您显示您在不同的范围内操作.看看下面的代码: def d2(obj) puts "in the scope of method :d2,I am operating as #{self}" puts "---" obj.define_singleton_method(:say2) do puts "in the scope of this closure,I am operating as #{self}" end end 简而言之,原因在于范围.每当你声明bound = msg时,你正在使用方法的msg本地内容,然后闭包然后可以获取msg的本地绑定值. 如果你想了解更多关于它是如何工作的,我强烈推荐“实用程序员 – 元编程Ruby”你会学到很多关于自我和闭包的知识. – – 编辑 – – def p 不同于 def d2(obj) 它是不同的,因为块内的自我是不同的.在方法定义“p”中,块可以访问实例变量和方法,而方法“d2”有一个只能访问Object的块.我们可以通过一点点monkeypatching来证明这一点.添加此代码: class Object??def msg?????“再见”??结束 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- Oracle 创建用户以及表空间Sql
- Cocos2dx v3.9 Mac OS 环境配置
- c# – 由于缺少XSD文件,无法反序列化xml-doc
- UICollectionView 实现,自动滚动、一屏横向显示3个view
- 深入入门正则表达式(java) - 3 - 正则在java中的使用
- 解决SOAP错误[Client] looks like we got no XML document
- ruby – 如何在watir-webdriver中查看适用于HTML元素的CSS样
- ruby-on-rails – 在Rails中同步locale yml文件工具
- 创建并增强Dojo类
- ruby-on-rails – 任何人都可以推荐一个不依赖脚手架的Ruby