ruby - "class << Class"(尖括号)语法的目的是什么?

标签 ruby class syntax

为什么我要使用 class << Class 向类中添加任何内容?语法?

class Fun
    def much_fun
        # some code here
    end
end

class << Fun # the difference is here!
    def much_more_fun
        # some code here
    end
end

而不是使用 monkey patching/duck punching 方法:

class Fun
    def much_fun
        # some code here
    end
end

class Fun # the difference is here!
    def much_more_fun
        # some code here
    end
end

阅读时Why's Poignant Guide to Ruby我遇到了:

为什么要定义一个类 LotteryDraw :

class LotteryDraw
    # some code here
    def LotteryDraw.buy( customer, *tickets )
        # some code here as well
    end
end

并在一段时间后向 LotteryDraw 添加了一个方法类:

class << LotteryDraw
    def play
        # some code here
    end
end

说:

When you see class << obj, believe in your heart, I’m adding directly to the definition of obj.

这个语法的目的是什么?为什么为什么决定这样做而不是使用猴子修补方法?


这些是一些相关的问题和网站:

最佳答案

需要多解释一下。在 ruby​​ 中,几乎每个对象都可以创建一个奇怪的东西,称为实例类。这个东西就像一个普通的类,主要区别在于它只有一个实例,并且该实例是在该类之前创建的。

简而言之,有了 A 类,您可以:

a = A.new
b = A.new

两者,ab现在是类 A 的实例,并且可以访问此类中定义的所有实例方法。现在让我们说,我们想添加一个只能由 a 访问的额外方法, 但不是 b (这在某些情况下可能很有用,但尽可能避免使用)。所有的方法都在类中定义,所以我们似乎需要将它添加到类 A,但这样它就可以通过 b 访问。以及。在这种情况下,我们需要为 a 创建一个实例类目的。为此,我们使用 class << <object>语法:

class << a
  def foo
  end
end

a.foo #=> nil
b.foo #=> undefined method

简而言之,class << <object>为给定对象打开一个实例类,允许为给定实例定义额外的实例方法,这些方法在任何其他对象上都不可用。

现在,话虽这么说:在 Ruby 中,类只是类 Class 的实例。这:

class A
end

几乎等同于(这里的区别不重要)

A = Class.new

所以如果类是对象,它们可以创建它们的实例类。

class << A
  def foo
  end
end

A.foo  #=> nil
Class.new.foo #=> undefined method

通常用于给给定的类添加所谓的类方法,但关键是实际上您是在类的实例类上创建实例方法。

关于ruby - "class << Class"(尖括号)语法的目的是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33453063/

相关文章:

ruby - 在ruby中按整数递增字符串

java - java 二进制文件未找到类异常

c++ - 通过初始化列表调用另一个类的构造函数。有问题

html - HTML5 语法中的 "Text"是否表示 "any character"?

javascript - 我可以在 javascript/html/css 中制作一个 ruby​​ GUI 吗?

ruby - 调用关闭和 splats

c++ - 返回值是类名后跟一对空括号是什么意思?

ruby - 在 Ruby 中更优雅的方式来做到这一点

ruby-on-rails - ruby rails : A way to save currency into a column within a database-table

c++ - 无法在没有对象的情况下调用成员函数 std::string Sportist::getIme()