Ruby中的自我成语

class << self在Ruby中做什么?


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

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 )时,行为都会根据它所处的状态而变化。


我在这个博客中找到了关于class << self ,本Eigenclass class << self和不同类型的methods的超级简单解释。

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

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

    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
    

    什么课程“的事情:

    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
    在这里,我们给你hi单例类实例方法:a 。 它可以用class << hi来完成。
    hi#singleton_class拥有所有实例方法hi#class了,可能还有一些更( :a在这里)。

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


    顺便说一句 - 他们调用object的单例类 == metaclass == eigenclass

    链接地址: http://www.djcxy.com/p/4359.html

    上一篇: class << self idiom in Ruby

    下一篇: How to convert a string to lower or upper case in Ruby