代码之家  ›  专栏  ›  技术社区  ›  wilhelmtell

Ruby:定义类的计算结果是什么

  •  4
  • wilhelmtell  · 技术社区  · 14 年前

    在Ruby中,为什么定义一个类的计算结果是 nil

    3 回复  |  直到 14 年前
        1
  •  8
  •   Jörg W Mittag    14 年前

    nil ?

    没有。

    例如,见:

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

    定义一个方法也是如此:为什么它的计算结果是 ?

    实际上,也不是。定义方法的计算结果是实现定义的值。它的计算结果是实现定义的值的原因是到目前为止Ruby社区还没有就它应该返回什么达成共识。

    CompiledMethod 与该方法对应的对象。鲁宾尼乌斯就是这么做的。然而,这有一个问题:并非所有Ruby实现都编译它们的方法。不是所有的人都这样 编译它们,在定义时编译它们。例如,JRuby只在执行它们时才编译它们,更准确地说 他们被处决了20次。有时它不会编译它们 编译器。

    其他人说,它应该评估到 UnboundMethod 与该方法对应的对象。在这里,问题是没有单一的 未绑定方法 不是 转换 但它们本身不是对象。当它们转换为对象时,每次都会生成一个新对象。所以 将返回的对象实际上与所定义的方法不直接相关。另外,您希望如何处理未绑定的方法?唯一的情况是 使用未绑定的方法是包装一个我不能修改的已经存在的方法;但如果我有权访问定义,那么我就不需要包装它。

    第三个小组说,定义一个方法应该按照它的名字来计算。这似乎是一个有点武断的选择。事实上,我还没有看到任何令人信服的理由来解释为什么会这样。从字面上说,唯一的论点是,这将允许您使Ruby看起来更像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的一个变体。如果使用块定义方法,它将返回与该块对应的过程。换句话说,它返回一个与方法体相对应的可执行对象:

    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 是核心库的一部分,不再需要。

        2
  •  3
  •   Marc-André Lafortune    14 年前

    定义类不会计算为 nil ,它返回最后一个表达式的内容(如调用方法)

    class X
      2
    end  # => 2
    

    singleton = class << SomeClass; self; end ,虽然现在我们可以使用 SomeClass.singleton_class

    (这就是为什么以方法定义结尾的类返回

    self

    class X
      def foo
        :bar
      end
    
      self
    end # => X
    
        3
  •  1
  •   Derick Bailey    14 年前

    您可以通过调用Class.new{…}来实现该功能而不是使用class关键字。

    someclass = Class.new{
      def bar
        puts "baz"
      end
    }

    然后您可以通过为类var指定一个常量来命名该类。

    Foo = someclass

    instance1 = someclass.new
    instance2 = Foo.new
    
    instance1.bar  #=> baz
    instance2.bar  #=> baz