module Cnblog2jekyll
class << self
attr_accessor :username
[:archive_links, :article_links].each do |method_name|
define_method method_name do
instance_value = instance_variable_get(("@" + method_name.to_s).to_sym)
instance_value ? instance_value : send("get_" + method_name.to_s)
# @archive_links ? @archive_links : get_archive_links
end
end
binding.pry
def test
binding.pry
end
end
end
请忽略大多数零件代码的含义并注意'binding.pry'的位置。
问题出现了:我在'binding.pry'的地方在pry控制台输入'self',它给出了这个结果:
From: /home/yanying/cnblog2jekyll/lib/cnblog2jekyll.rb @ line 20 :
15: instance_value = instance_variable_get(("@" + method_name.to_s).to_sym)
16: instance_value ? instance_value : send("get_" + method_name.to_s)
17: # @archive_links ? @archive_links : get_archive_links
18: end
19: end
=> 20: binding.pry
21:
22: def test
23: binding.pry
24: end
25:
[1] pry(#<Class>)> self
=> #<Class:Cnblog2jekyll>
[2] pry(#<Class>)> self.class
=> Class
[3] pry(#<Class>)> self.ancestors
=> [#<Class:Cnblog2jekyll>, Module, Object, PP::ObjectMixin, Kernel, BasicObject]
[4] pry(#<Class>)>
=> true
[2] pry(main)> Cnblog2jekyll.test
From: /home/yanying/cnblog2jekyll/lib/cnblog2jekyll.rb @ line 23 Cnblog2jekyll.test:
22: def test
=> 23: binding.pry
24: end
[1] pry(Cnblog2jekyll)> self
=> Cnblog2jekyll
[2] pry(Cnblog2jekyll)> self.class
=> Module
[3] pry(Cnblog2jekyll)> self.ancestors
=> [Cnblog2jekyll]
[4] pry(Cnblog2jekyll)>
所以,我的问题是:为什么'self'的第一个结果是'Class'?但第二个是“模块”?这里的魔力是什么?
答案 0 :(得分:4)
由于您使用的是class << self
,因此您打开了一个self
单例类,其中的方法重新定义了当前self
的方法,在您的情况下为{{1} }}
如果你有:
module Cnblog2jekyll
你打电话给class Cnblog2jekyll
def foo
end
class << self
def bar
end
end
end
你得到一个Cnblog2jekyll.new.bar
,因为bar被指定为类方法,而不是对象方法。在您的情况下,您的方法是undefined_method
方法,因为module
位于模块块内。
查看关于class << self
习语的this question以及关于它的this article。
答案 1 :(得分:1)
让我先回答你问题的第二部分。与其他语言相比,ruby中的类并不特别。
因此,类只是Ruby中所有其他类的对象。 Ruby中的所有类都是Class
类的实例,包括Class
类本身。现在,Module
也是一个类,偶然是Class
的父类。在Ruby中,你基本上有这个设置:
class BasicObject
# The top-level base class. All objects in Ruby are an instance of BaseClass.
# This class is effectively empty and is generally of little use on its own.
end
module Kernel
# A module which is included about everywhere. It implements most of the basic
# core methods of Ruby which you use every day including puts, raise and
# require
end
class Object < BasicObject
include Kernel
# Almost all objects on ruby are instances of Object. Here, Ruby defines many
# convenience methods available to about all objects, e.g., to_s, is_a? and
# nil?
end
class Module < Object
# A "special" class. All modules are an instance of this class. In fact, this:
#
# module Foo
# end
#
# is mostly equivalent to
#
# Foo = Module.new
end
class Class < Module
# All classes are also modules. In fact, a class is basically a module which
# can't be included or extended but can be instantiated.
#
# All objects in Ruby are instances of the Class class. This is where the
# ring is closed. Because of this, you will see the ancestors chain the
# way you got it from Pry.
end
你看,基础对象模型有点圆。这种结构是硬编码的,以便引导所谓的语言元模型。所有对象(包括类)都建立在这个基本结构上。
现在问题的第一部分:您在指定的类的上下文中调用pry,因此,self
是您当前正在创建的类。请参阅Gabriel Lett的答案,了解其工作原理的详细信息。