Ruby:关于定义类的定义
在
Ruby中,为什么定义一个类的值为nil?定义方法也是如此:为什么它评估为nil?如果定义一个类会被评估为类,那会不会有用?
解决方法
它没有. 首先,在Ruby中你没有定义一个类,你执行一个类体.其次,执行一个类体并不会像你声称的那样求值为nil,它会计算出类体内最后一个表达式的值.这与执行模块体和执行方法体完全一致. 例如,见: class Foo 'Hello' end # => 'Hello'
实际上,它也没有.定义方法将计算为实现定义的值.它评估实现定义值的原因是,到目前为止,Ruby社区尚未就应该返回的内容达成共识. 有人认为它应该评估对应于该方法的CompiledMethod对象.这就是Rubinius所做的.但是,这有一个问题:并非所有Ruby实现都编译它们的方法.并非所有人都编译它们,在定义时编译它们.例如,JRuby只在执行它们时才编译它们,更确切地说是在执行了20次之后.有时它根本不编译它们,例如在禁止编译的环境中,例如Google App Engine.此外,并非所有Ruby实现都为其编译方法提供了Ruby表示.即使他们这样做,他们的编译方法也大不相同:Rubinius的编译方法是Rubinius字节码,YARV的编译方法是YARV字节码,JRuby的编译方法是JVM字节码,IronRuby的编译方法是DLR树.当然,最广泛使用的实现,MRI,甚至没有编译器. 其他人说,它应该评估对应于该方法的UnboundMethod对象.这里的问题是没有一个UnboundMethod对象对应一个方法.其中有无数的. Ruby方法不是对象.它们可以转换为对象,但它们本身不是对象.当它们转换为对象时,它们每次都会生成一个新对象.因此,将返回的UnboundMethod对象实际上与定义的方法没有直接关系.另外,你想用未绑定的方法做什么?我使用未绑定方法的唯一情况是包装一个我无法修改的现有方法;但是,如果我仍然可以访问该定义,那么我不需要包装它. 第三组表示定义方法应评估其名称.这似乎是一种随意的选择.事实上,我没有看到为什么会出现这种情况的任何令人信服的理由.从字面上看,唯一的论点就是这会让你看起来更像Java: # here's how you make a single method private today def foo(bar) end private :foo # instead you could do this: private def foo(bar) end 所以,基本上,方法定义返回实现定义值(大多数实现只是零)的原因是没有人提出更好的建议. 有趣的是,Module#define_method确实返回了一些有用的东西.如果使用方法定义方法,则返回旧方法.如果使用proc来定义方法,则返回该proc的变体.如果使用块来定义方法,则返回与该块对应的proc.换句话说,它返回一个对应于方法体的可执行对象: class Foo $bar = ->{} $baz = define_method :baz,$bar $qux = instance_method :baz $quux = define_method :quux,$qux define_method :corge do;end end # => #<Proc:0x1cda900@(irb):8 (lambda)> $bar.eql? $baz # => true $bar.equal? $baz # => false $qux.equal? $quux # => true
为什么?它现在的方式,类主体可以返回任何你想要的东西,包括类.根据你的建议,它只能返回类,所以它的功能将严格降低. 另外,唯一的例子是我需要一个类体来返回类本身,用于获取对象的单例类的引用,如下所示: foo = Object.new foo_singleton_class = class << foo; self end 或者更为人熟知的模式: class Object; def singleton_class; class << self; self end end end 但是现在Object#singleton_class是核心库的一部分,不再需要了. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |