类<< Ruby 中的自我习语

发布于 2024-08-26 11:33:34 字数 59 浏览 6 评论 0 原文

class << 是什么意思? self 在 Ruby 中做什么?

What does class << self do in Ruby?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

撞了怀 2024-09-02 11:33:34

首先,类<< foo 语法打开了 foo 的单例类(eigenclass)。这允许您专门化在该特定对象上调用的方法的行为。

a = 'foo'
class << a
  def inspect
    '"bar"'
  end
end
a.inspect   # => "bar"

a = 'foo'   # new object, new singleton class
a.inspect   # => "foo"

现在,回答这个问题:class << self 打开了 self 的单例类,以便可以为当前 self 对象重新定义方法(在类或模块体内是类或模块本身)。通常,这用于定义类/模块(“静态”)方法:

class String
  class << self
    def value_of obj
      obj.to_s
    end
  end
end

String.value_of 42   # => "42"

这也可以写为简写:

class String
  def self.value_of obj
    obj.to_s
  end
end

或更短:

def String.value_of obj
  obj.to_s
end

在函数定义内部时,self 指的是该函数的对象正在被调用。在这种情况下,class << self 打开该对象的单例类;它的一个用途是实现穷人的状态机:

class StateMachineExample
  def process obj
    process_hook obj
  end

private
  def process_state_1 obj
    # ...
    class << self
      alias process_hook process_state_2
    end
  end

  def process_state_2 obj
    # ...
    class << self
      alias process_hook process_state_1
    end
  end

  # Set up initial state
  alias process_hook process_state_1
end

因此,在上面的示例中,StateMachineExample 的每个实例都有 process_hook 别名为 process_state_1 ,但请注意后者如何将 process_hook (仅适用于 self,不影响其他 StateMachineExample 实例)重新定义为 process_state_2< /代码>。因此,每次调用者调用 process 方法(调用可重新定义的 process_hook)时,行为都会根据其所处的状态而变化。

First, the class << foo syntax opens up foo's singleton class (eigenclass). This allows you to specialise the behaviour of methods called on that specific object.

a = 'foo'
class << a
  def inspect
    '"bar"'
  end
end
a.inspect   # => "bar"

a = 'foo'   # new object, new singleton class
a.inspect   # => "foo"

Now, to answer the question: class << self opens up self's singleton class, so that methods can be redefined for the current self object (which inside a class or module body is the class or module itself). Usually, this is used to define class/module ("static") methods:

class String
  class << self
    def value_of obj
      obj.to_s
    end
  end
end

String.value_of 42   # => "42"

This can also be written as a shorthand:

class String
  def self.value_of obj
    obj.to_s
  end
end

Or even shorter:

def String.value_of obj
  obj.to_s
end

When inside a function definition, self refers to the object the function is being called with. In this case, class << self opens the singleton class for that object; one use of that is to implement a poor man's state machine:

class StateMachineExample
  def process obj
    process_hook obj
  end

private
  def process_state_1 obj
    # ...
    class << self
      alias process_hook process_state_2
    end
  end

  def process_state_2 obj
    # ...
    class << self
      alias process_hook process_state_1
    end
  end

  # Set up initial state
  alias process_hook process_state_1
end

So, in the example above, each instance of StateMachineExample has process_hook aliased to process_state_1, but note how in the latter, it can redefine process_hook (for self only, not affecting other StateMachineExample instances) to process_state_2. So, each time a caller calls the process method (which calls the redefinable process_hook), the behaviour changes depending on what state it's in.

输什么也不输骨气 2024-09-02 11:33:34

我找到了关于 class << 的超级简单解释selfEigenclass 和不同类型的方法。

在 Ruby 中,可以将三种类型的方法应用于类:

  1. 实例方法
  2. Singleton 方法
  3. 类方法

实例方法和类方法几乎与其他编程语言中的同名异义相似。

class Foo  
  def an_instance_method  
    puts "I am an instance method"  
  end  
  def self.a_class_method  
    puts "I am a class method"  
  end  
end

foo = Foo.new

def foo.a_singleton_method
  puts "I am a singletone method"
end

访问Eigenclass(包括单例方法)的另一种方法是使用以下语法(class <<):

foo = Foo.new

class << foo
  def a_singleton_method
    puts "I am a singleton method"
  end
end

现在您可以为定义单例方法self 在此上下文中是类 Foo 本身:

class Foo
  class << self
    def a_singleton_and_class_method
      puts "I am a singleton method for self and a class method for Foo"
    end
  end
end

I found a super simple explanation about class << self , Eigenclass and different type of methods.

In Ruby, there are three types of methods that can be applied to a class:

  1. Instance methods
  2. Singleton methods
  3. Class methods

Instance methods and class methods are almost similar to their homonymous in other programming languages.

class Foo  
  def an_instance_method  
    puts "I am an instance method"  
  end  
  def self.a_class_method  
    puts "I am a class method"  
  end  
end

foo = Foo.new

def foo.a_singleton_method
  puts "I am a singletone method"
end

Another way of accessing an Eigenclass(which includes singleton methods) is with the following syntax (class <<):

foo = Foo.new

class << foo
  def a_singleton_method
    puts "I am a singleton method"
  end
end

now you can define a singleton method for self which is the class Foo itself in this context:

class Foo
  class << self
    def a_singleton_and_class_method
      puts "I am a singleton method for self and a class method for Foo"
    end
  end
end
以歌曲疗慰 2024-09-02 11:33:34

通常,实例方法是全局方法。这意味着它们在定义它们的类的所有实例中都可用。相反,单例方法是在单个对象上实现的。

Ruby 将方法存储在类中,并且所有方法都必须与类关联。定义单例方法的对象不是类(它是类的实例)。如果只有类才能存储方法,那么对象怎么能存储单例方法呢?创建单例方法时,Ruby 会自动创建一个匿名类来存储该方法。这些匿名类称为元类,也称为单例类或特征类。单例方法与元类相关联,元类又与定义单例方法的对象相关联。

如果在单个对象中定义了多个单例方法,则它们都存储在同一个元类中。

class Zen
end

z1 = Zen.new
z2 = Zen.new

class << z1
  def say_hello
    puts "Hello!"
  end
end

z1.say_hello    # Output: Hello!
z2.say_hello    # Output: NoMethodError: undefined method `say_hello'…

在上面的例子中,class << z1 改变当前的 self 指向 z1 对象的元类;然后,它在元类中定义 say_hello 方法。

类也是对象(称为 Class 的内置类的实例)。类方法只不过是与类对象关联的单例方法。

class Zabuton
  class << self
    def stuff
      puts "Stuffing zabuton…"
    end
  end
end

所有对象都可能有元类。这意味着类也可以有元类。在上面的例子中,class << self 修改 self,使其指向 Zabuton 类的元类。当一个方法在没有显式接收者(将在其上定义该方法的类/对象)的情况下定义时,它会在当前范围内隐式定义,即 self 的当前值。因此,stuff 方法是在 Zabuton 类的元类中定义的。上面的示例只是定义类方法的另一种方式。恕我直言,最好使用 def self.my_new_clas_method 语法来定义类方法,因为它使代码更容易理解。包含上面的示例是为了让我们了解当我们遇到类 << 时会发生什么。自我语法。

其他信息可以在这篇关于 Ruby 类的文章中找到。

Usually, instance methods are global methods. That means they are available in all instances of the class on which they were defined. In contrast, a singleton method is implemented on a single object.

Ruby stores methods in classes and all methods must be associated with a class. The object on which a singleton method is defined is not a class (it is an instance of a class). If only classes can store methods, how can an object store a singleton method? When a singleton method is created, Ruby automatically creates an anonymous class to store that method. These anonymous classes are called metaclasses, also known as singleton classes or eigenclasses. The singleton method is associated with the metaclass which, in turn, is associated with the object on which the singleton method was defined.

If multiple singleton methods are defined within a single object, they are all stored in the same metaclass.

class Zen
end

z1 = Zen.new
z2 = Zen.new

class << z1
  def say_hello
    puts "Hello!"
  end
end

z1.say_hello    # Output: Hello!
z2.say_hello    # Output: NoMethodError: undefined method `say_hello'…

In the above example, class << z1 changes the current self to point to the metaclass of the z1 object; then, it defines the say_hello method within the metaclass.

Classes are also objects (instances of the built-in class called Class). Class methods are nothing more than singleton methods associated with a class object.

class Zabuton
  class << self
    def stuff
      puts "Stuffing zabuton…"
    end
  end
end

All objects may have metaclasses. That means classes can also have metaclasses. In the above example, class << self modifies self so it points to the metaclass of the Zabuton class. When a method is defined without an explicit receiver (the class/object on which the method will be defined), it is implicitly defined within the current scope, that is, the current value of self. Hence, the stuff method is defined within the metaclass of the Zabuton class. The above example is just another way to define a class method. IMHO, it's better to use the def self.my_new_clas_method syntax to define class methods, as it makes the code easier to understand. The above example was included so we understand what's happening when we come across the class << self syntax.

Additional info can be found at this post about Ruby Classes.

弥枳 2024-09-02 11:33:34

什么类<< thing 的作用是:

class Hi
  self #=> Hi
  class << self #same as 'class << Hi'
    self #=> #<Class:Hi>
    self == Hi.singleton_class #=> true
  end
end

[它使得self == thing.singleton_class在其块的上下文中]


thing.singleton_class是什么?

hi = String.new
def hi.a
end

hi.class.instance_methods.include? :a #=> false
hi.singleton_class.instance_methods.include? :a #=> true

hi 对象从其 #singleton_class.instance_methods 继承其 #methods,然后从其 #class.instance_methods 继承。< br>
这里我们给出了hi单例类实例方法:a。这可以通过 class << 来完成。嗨
hi#singleton_class 具有 hi#class 具有的所有实例方法,可能还有更多 (<代码>:a此处)。

[事物的实例方法 #class #singleton_class 可以直接应用于事物。当 ruby​​ 看到 thing.a 时,它首先在 thing.singleton_class.instance_methods 中查找方法定义,然后在 thing.class.instance_methods 中查找]


顺便说一下 - 他们调用对象的单例类 == 元类 == 特征类

What class << thing does:

class Hi
  self #=> Hi
  class << self #same as 'class << Hi'
    self #=> #<Class:Hi>
    self == Hi.singleton_class #=> true
  end
end

[it makes self == thing.singleton_class in the context of its block].


What is thing.singleton_class?

hi = String.new
def hi.a
end

hi.class.instance_methods.include? :a #=> false
hi.singleton_class.instance_methods.include? :a #=> true

hi object inherits its #methods from its #singleton_class.instance_methods and then from its #class.instance_methods.
Here we gave hi's singleton class instance method :a. It could have been done with class << hi instead.
hi's #singleton_class has all instance methods hi's #class has, and possibly some more (:a here).

[instance methods of thing's #class and #singleton_class can be applied directly to thing. when ruby sees thing.a, it first looks for :a method definition in thing.singleton_class.instance_methods and then in thing.class.instance_methods]


By the way - they call object's singleton class == metaclass == eigenclass.

牵强ㄟ 2024-09-02 11:33:34

单例方法是仅为单个对象定义的方法。

示例:

class SomeClass
  class << self
    def test
    end
  end
end

test_obj = SomeClass.new

def test_obj.test_2
end

class << test_obj
  def test_3
  end
end

puts "Singleton's methods of SomeClass"
puts SomeClass.singleton_methods
puts '------------------------------------------'
puts "Singleton's methods of test_obj"
puts test_obj.singleton_methods

SomeClass 的 Singleton 方法

test


test_obj 的 Singleton 方法

test_2

test_3 >

А singleton method is a method that is defined only for a single object.

Example:

class SomeClass
  class << self
    def test
    end
  end
end

test_obj = SomeClass.new

def test_obj.test_2
end

class << test_obj
  def test_3
  end
end

puts "Singleton's methods of SomeClass"
puts SomeClass.singleton_methods
puts '------------------------------------------'
puts "Singleton's methods of test_obj"
puts test_obj.singleton_methods

Singleton's methods of SomeClass

test


Singleton's methods of test_obj

test_2

test_3

一城柳絮吹成雪 2024-09-02 11:33:34

事实上,如果您为 Ruby 项目编写任何 C 扩展,那么实际上只有一种方法来定义 Module 方法。

rb_define_singleton_method

我知道这种自助业务只会带来各种其他问题,因此您可以通过搜索每个部分做得更好。

先有对象。

foo = Object.new

我可以为 foo 创建一个方法吗?

当然

def foo.hello
 'hello'
end

我该怎么办?

foo.hello
 ==>"hello"

只是另一个对象。

foo.methods

您将获得所有对象方法以及新方法。

def foo.self
 self
end

foo.self

只是 foo 对象。

尝试看看如果您从其他对象(例如类和模块)创建 foo 会发生什么。所有答案中的示例都很好用,但您必须使用不同的想法或概念才能真正理解代码的编写方式发生了什么。现在您有很多术语需要查看。

单例,
班级,
模块,
自己,
目的,
Eigenclass 被提出,但 Ruby 并没有这样命名对象模型。它更像是元类。
理查德或 __why 在这里向您展示这个想法。
http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html
如果这让您大吃一惊,请尝试在搜索中查找 Ruby 对象模型。
我在 YouTube 上知道的两个视频是 Dave Thomas 和 Peter Cooper。他们也试图解释这个概念。戴夫花了很长时间才拿到它,所以不用担心。
我也在努力。不然我为什么会在这里?
谢谢你的提问。
另请查看标准库。它有一个单例模块(仅供参考)。

这很好。
https://www.youtube.com/watch?v=i4uiyWA8eFk

In fact if you write any C extensions for your Ruby projects there is really only one way to define a Module method.

rb_define_singleton_method

I know this self business just opens up all kinds of other questions so you could do better by searching each part.

Objects first.

foo = Object.new

Can I make a method for foo?

Sure

def foo.hello
 'hello'
end

What do I do with it?

foo.hello
 ==>"hello"

Just another object.

foo.methods

You get all the Object methods plus your new one.

def foo.self
 self
end

foo.self

Just the foo Object.

Try to see what happens if you make foo from other Objects like Class and Module. The examples from all the answers are nice to play with but you have to work with different ideas or concepts to really understand what is going on with the way the code is written. So now you have lots of terms to go look at.

Singleton,
Class,
Module,
self,
Object,
and Eigenclass was brought up but Ruby doesn't name Object Models that way. It's more like Metaclass.
Richard or __why shows you the idea here.
http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html
And if the blows you away then try looking up Ruby Object Model in search.
Two videos that I know of on YouTube are Dave Thomas and Peter Cooper. They try to explain that concept too. It took Dave a long time to get it so don't worry.
I'm still working on it too. Why else would I be here?
Thanks for your question.
Also take a look at the standard library. It has a Singleton Module just as an FYI.

This is pretty good.
https://www.youtube.com/watch?v=i4uiyWA8eFk

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文