【问题标题】:Creating anonymous classes in ruby在 ruby​​ 中创建匿名类
【发布时间】:2021-11-18 10:45:53
【问题描述】:

根据示例中的“well ground ruby​​ist”,c“包含”或“指向”一个匿名类。我是对的,C 不是匿名类吗?这真的有点令人困惑。

    >> c = Class.new
    => #<Class:0x0000000006c4bd40>
    >> o1 = c.new
    => #<#<Class:0x0000000006c4bd40>:0x0000000006b81ec8>
    >> o1.class
    => #<Class:0x0000000006c4bd40>
    >>
    >> C = Class.new
    => C
    >> o2 = C.new
    => #<C:0x0000000006494480>
    >> o2.class
    => C

【问题讨论】:

    标签: ruby anonymous-class


    【解决方案1】:
    • Class.new 创建一个新的匿名(未命名)类

    • c = Class.new 创建一个新的匿名类并将其分配给 局部变量 c

    • C = Class.new 创建一个新的匿名类并将其分配给 constant C

    虽然两个赋值看起来几乎相同,但有一个微妙但重要的区别:将匿名类分配给 constant 将该类的 name 设置为常量的名称:

    c = Class.new
    c.name #=> nil
    
    C = Class.new
    C.name #=> "C"
    

    Class.new 的文档中也提到了这一点:

    您可以通过将类对象分配给常量来为类命名。

    此时,该类不再是匿名的。它现在有了一个名称,我们可以使用该名称以常量C 的形式引用它。

    【讨论】:

    • 谢谢,就是这样!
    • 可能值得注意的是,Module#const_set 可用于将匿名类 c = Class.new 分配给常量:Object.const_set('C', c); C == c #=&gt; true; C.name #=&gt; "C"
    • @Cary:即使这样也有效:&gt;&gt; c = Class.new; =&gt; #&lt;Class:0x000000000681d9d0&gt; &gt;&gt; C = c; =&gt; C &gt;&gt; c.name; =&gt; "C"
    【解决方案2】:

    “匿名”或“命名”类的概念在 Ruby 中没有真正意义。类只是一个对象,就像任何其他对象一样。我们也没有“匿名”或“命名”整数或字符串。类只是一个像整数或字符串一样的对象:它可以从方法返回,可以分配给局部变量、实例变量、类变量、全局变量或常量。

    这与 Java 等具有主格类型系统的编程语言不同,后者有或没有名称的类型会产生很大的不同。

    理解这一点非常重要:一个类只是一个对象,它恰好是Class 类的一个实例。没什么特别的。它只是一个像整数、字符串或数组这样的对象。

    什么类(实际上是模块),是一个名为Module#name 的方法,但同样,该方法并没有什么特别之处。您也可以将#name 方法添加到您自己的类中。

    唯一的特别之处在于,当一个类(实际上是一个模块)被赋值时(无论是使用赋值运算符=,还是反射性地使用Module#const_set方法),第一次到一个常量,那个常量的路径变成了Module#name的返回值:

    a = Module.new
    a.name #=> nil
    
    b = a
    b.name #=> nil
    
    module A; module B; module C; end end end
    
    A::B::C.const_set(:D, b)
    
    a.name #=> 'A::B::C::D'
    
    A::B::C::D = nil
    A::B::C.send(:remove_const, :D)
    A::B::C = nil
    A::B.send(:remove_const, :C)
    A::B = nil
    A.send(:remove_const, :B)
    A = nil
    Object.send(:remove_const, :A)
    
    a.name #=> 'A::B::C::D'
    

    因此,如您所见,“匿名”和“命名”之间的区别实际上是不存在的,即使您可以构造一个有意义的定义,那么区别仍然无关紧要。

    【讨论】:

      猜你喜欢
      • 2011-09-16
      • 2015-11-16
      • 2010-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多