加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Ruby:关于定义类的定义

发布时间:2020-12-17 04:03:24 所属栏目:百科 来源:网络整理
导读:在 Ruby中,为什么定义一个类的值为nil?定义方法也是如此:为什么它评估为nil?如果定义一个类会被评估为类,那会不会有用? 解决方法 In Ruby,why does defining a class evaluate to nil ? 它没有. 首先,在Ruby中你没有定义一个类,你执行一个类体.其次,执行
在 Ruby中,为什么定义一个类的值为nil?定义方法也是如此:为什么它评估为nil?如果定义一个类会被评估为类,那会不会有用?

解决方法

In Ruby,why does defining a class evaluate to nil?

它没有.

首先,在Ruby中你没有定义一个类,你执行一个类体.其次,执行一个类体并不会像你声称的那样求值为nil,它会计算出类体内最后一个表达式的值.这与执行模块体和执行方法体完全一致.

例如,见:

class Foo
  'Hello'
end
# => 'Hello'

Same goes for defining a method: why does it evaluate to nil?

实际上,它也没有.定义方法将计算为实现定义的值.它评估实现定义值的原因是,到目前为止,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

Wouldn’t it be useful if defining a class would evaluate as the class?

为什么?它现在的方式,类主体可以返回任何你想要的东西,包括类.根据你的建议,它只能返回类,所以它的功能将严格降低.

另外,唯一的例子是我需要一个类体来返回类本身,用于获取对象的单例类的引用,如下所示:

foo = Object.new
foo_singleton_class = class << foo; self end

或者更为人熟知的模式:

class Object; def singleton_class; class << self; self end end end

但是现在Object#singleton_class是核心库的一部分,不再需要了.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读