标签: eigenclass

类,模块,它们的本征类和方法查找

让我们打开课程Module并为其添加一个方法:

class Module  
  def foo  
    puts "phew"  
  end  
end
Run Code Online (Sandbox Code Playgroud)

我可以通过这样做来调用这个方法,

Class.foo
Run Code Online (Sandbox Code Playgroud)

这是可以理解的,因为ClassClass超类的类Module.所以它可以调用中定义的实例方法Module.

类和模块之间的关系

现在,bar下面的方法是在Module'eigenclass 上定义的:

class Module  
   def self.bar  
     puts "bar"  
   end  
end
Run Code Online (Sandbox Code Playgroud)

但现在

Class.bar 
Run Code Online (Sandbox Code Playgroud)

也有效.

有人可以解释一下如何在特征类Class中访问方法Module吗?


我想我现在明白了.方法查找不像我之前解释的那样工作.当我这样做的时候Class.foo,这个方法是在特征Class类中进行搜索,然后是超类,它是本Module征类的特征类,直到它的特征类BasicObject,此时它会转向自身(就像蛇吃它自己的尾巴)来寻找方法Class(就像'eigenclass Class的超类BasicObject一样)然后到它的超类Module,它找到了方法.

类似地,当我这样做时Class.bar,方法在Class's eigenclass中搜索,然后在Module它找到它的本征类中搜索.

当我做

class Class   
  def check  
    puts "class instance method"  
  end
end …
Run Code Online (Sandbox Code Playgroud)

ruby lookup module class eigenclass

5
推荐指数
1
解决办法
618
查看次数

如何在特征类中使模块常量也可见?

我创建了一个包含常量NAME和方法的模块hello.如果类包含模块,则两个定义应在不同范围内可见.

module A
  NAME = 'Otto'
  def self.included(base)
    base.extend(ClassMethods)
  end

  def hello(name = 'world')
    self.class.hello(name)
  end

  module ClassMethods
    def hello(name = 'world')
      "Hello #{name}!"
    end
  end
end

class B
  include A

  def instance_scope
    p [__method__, hello(NAME)]
  end

  def self.class_scope
    p [__method__, hello(NAME)]
  end

  class << self
    def eigen_scope
      p [__method__, hello(NAME)]
    end
  end
end

B.new.instance_scope
B.class_scope
B.eigen_scope

#=> script.rb:34:in `eigen_scope': uninitialized constant Class::NAME (NameError)
    from script.rb:41
Run Code Online (Sandbox Code Playgroud)

但是常量在本征类的实例方法范围中是不可见的class << self.

有没有办法使模块更健壮,并在上面的错误范围内提供常量?

ruby metaprogramming eigenclass

5
推荐指数
1
解决办法
169
查看次数

Ruby中单例类的BasicObject的Singleton类

这主要是一个"学术"的,但在这里:

根据这个Ruby eigenclass图(略加编辑):

可能是错误的Ruby特征类图

BasicObject.singleton_class.singleton_class.superclassClass.

但是,在Ruby解释器(Ruby v2.5.1)上运行它,事实证明它BasicObject.singleton_class.singleton_class.superclass#<Class:Class>和不是Class.因此,图表是说谎还是我遗漏了什么?

该图来自我在Freenode的Ruby IRC聊天的用户.但是,它被多次引用给许多其他用户,它被视为Ruby对象模型圣经.

ruby metaprogramming eigenclass

5
推荐指数
1
解决办法
253
查看次数

ruby什么时候才能成为特征类

在对象或类上定义单例方法之前是否存在Eigenclasses.即当定义单例方法或类方法时,它们是否总是存在或存在?

ruby eigenclass

4
推荐指数
1
解决办法
158
查看次数

Ruby eigenclass意外行为

首先,让我们添加一个方法来检索"从此博客帖子中复制"的特征类

class Object 
  def eigenclass 
    class << self
      self
    end 
  end 
end
Run Code Online (Sandbox Code Playgroud)

然后创建一个简单的类

class A
end

puts A.new.eigenclass.superclass      # => A
puts Class.new.eigenclass.superclass  # => #<Class:Object>
Run Code Online (Sandbox Code Playgroud)

我期待第二次投入输出Class

任何线索为什么会这样?

ruby metaprogramming eigenclass

4
推荐指数
1
解决办法
193
查看次数

动态地将模块中的方法添加到类的特定实例

这是交易:我需要用一些方法扩展class Box的特定实例.我需要包含实时内部模块的方法,我希望Box实例能够动态地包含模块.现在我使用带有eval的钩子:

class Box
  def after_initialize
    if self.injected_module.present?
      eval("class << self; include #{self.injected_module}; end")
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

它工作得很好但是当我使用eval时我真的感觉很脏.我正在寻找类似的东西:

module_to_inject = self.injected_module
self.eigenclass.class_eval do
   include module_to_inject
end
Run Code Online (Sandbox Code Playgroud)

但是我无法让eigenclass在没有monkeypatching类的情况下运行class_eval:

class Box; def eigenclass; class << self; self; end end end
Run Code Online (Sandbox Code Playgroud)

有一种美丽(可靠)的方式让我这样做吗?

ruby singleton eval local-variables eigenclass

3
推荐指数
1
解决办法
766
查看次数

Ruby 中的单例类是什么?

我无法理解红宝石中特征类单例类的概念。我读了很多,认为 eigenclass是一个类的类。这对我来说没有意义,因为对我来说,类的类实际上是Class因为所有类实际上都是类的实例Class

另一件我不太明白的事情是下面的说法:类方法实际上是类 eigenclass 的实例方法。特征类可以通过以下方式访问:

YourClass = Class.new
class << YourClass
  def class_method
  end
end
Run Code Online (Sandbox Code Playgroud)

但是,如果特征类确实是 YourClass 类(即Class),那么前面的代码不应该打开该类Class并向其添加实例方法class_method,使其可供所有未来的实例访问(即在未来)?

我实际上感觉单例类与Class. 当你这样做时:

class MyClass
end

MyClass.singleton_class
Run Code Online (Sandbox Code Playgroud)

你得到的#<Class:MyClass>结果与输出不同MyClass.class => Class

#<Class:MyClass>那个输出是什么?这与命名空间无关,否则会有两个:Class::MyClass...

我正在寻找对本征类概念的简单且明确的解释,以澄清我的想法。

ruby class eigenclass

3
推荐指数
1
解决办法
2432
查看次数

一个类和Ruby中该类的单例之间的区别是什么?

好的,所以我想在Ruby中做一些元编程,我有点困惑.根据我读过的几篇文章(像这一篇),为了动态地将类方法添加到Ruby类中,你必须使用类的单例类:

class Klass
end

class << Klass
  self.define_method(:foo) { return "foo" }
end
Run Code Online (Sandbox Code Playgroud)

这是为什么,与此有何不同?

class Klass
  self.define_method(:foo) { return "foo" }
end
Run Code Online (Sandbox Code Playgroud)

(对不起,如果这个问题包含任何错误的假设.就像我说的,我有点困惑.)

ruby eigenclass

2
推荐指数
1
解决办法
1883
查看次数

Ruby在Object中寻找类变量而不是特定的类

这部分有效:

 class Example1
   @@var1= "var1 in the Example1"
   def get_var1
     @@var1
   end
 end

 example1 = Example1.new
 example1.get_var1
 # => "var1 in the Example1"
Run Code Online (Sandbox Code Playgroud)

但如果我尝试eigenclass:

def example1.get_var1
  @@var1
end

example1.get_var1
# NameError: uninitialized class variable @@var1 in Object
# from (pry):128:in `get_var1'
Run Code Online (Sandbox Code Playgroud)

红宝石看起来@@var1Object代替Example.

我已经在Ruby 1.9.3和2.0中测试了这个代码并得到了相同的结果.

为什么会这样?
第二件事,我们可以将其关闭(因此example.get_var1不会在Object中查找类变量)吗?

ruby eigenclass

2
推荐指数
1
解决办法
227
查看次数

Ruby - 有没有办法获得特征类的实例?

我正在寻找一种方法来获取本征类的实例,因为每个本征类只有一个实例.

我可以通过ObjectSpace来测试每个本征类,但我猜它很昂贵.

奇怪的是,我必须得到每个对象的本征类来测试匹配,因为is_a?这还不够:

class A; end
class B < A; end

AA = class << A; self; end

p A.is_a? AA #=> true
p B.is_a? AA #=> true!!!!
Run Code Online (Sandbox Code Playgroud)

我希望有一个Class#instanceClass#instances方法来获取类(或本征类)的实例.

最直接的方法是从特征类中提取实例inspect,但我想知道我是否可以依赖它:

p AA         #=> #<Class:A>
instance = Object.const_get(AA.inspect.match(/^#<Class:(\w+)>$/)[1])
p instance   #=> A

# (this works for class' eigenclass)
Run Code Online (Sandbox Code Playgroud)

我的用例是我必须得到类方法的类,但是Method#owner给了我本征类,并Method#receiver给了我当前的接收器:

# Continuing previous example
def A.f; end
mtd = B.method(:f)
p mtd.owner     #=> #<Class:A>
p mtd.receiver  #=> B
# I …
Run Code Online (Sandbox Code Playgroud)

ruby instance eigenclass

1
推荐指数
1
解决办法
1002
查看次数