这个Ruby对Class.new做了什么来创建类, 请考虑以下代码: module MyClass def foo "method" end end
现在,我可以用通常的方法实例化这个类的一个新类这个Ruby对Class.new做了什么来创建类, 请考虑以下代码: module MyClass def foo "method" end end,ruby,metaprogramming,Ruby,Metaprogramming,现在,我可以用通常的方法实例化这个类的一个新类 @my_new_class = MyClass.new 或者,我可以做一些元编程魔术 @my_new_class = Class.new { include MyClass }.send :new 问题是这两者之间的区别是什么?上述代码(几乎)相当于: MyNewClass = Class.new { include MyClass } @my_new_class = MyNewClass.new 就像 class MyNewClass
@my_new_class = MyClass.new
或者,我可以做一些元编程魔术
@my_new_class = Class.new { include MyClass }.send :new
问题是这两者之间的区别是什么?上述代码(几乎)相当于:
MyNewClass = Class.new { include MyClass }
@my_new_class = MyNewClass.new
就像
class MyNewClass
include MyClass
end
@my_new_class = MyNewClass.new
使用动态声明匿名新类:
使用给定的超类(如果未给定参数,则使用对象)创建一个新的匿名(未命名)类。通过将类对象指定给常量,可以为类命名
如果给定一个块,它将被传递给类对象,并使用class\u eval
在该类的上下文中计算该块
上述代码(几乎)相当于:
MyNewClass = Class.new { include MyClass }
@my_new_class = MyNewClass.new
就像
class MyNewClass
include MyClass
end
@my_new_class = MyNewClass.new
使用动态声明匿名新类:
使用给定的超类(如果未给定参数,则使用对象)创建一个新的匿名(未命名)类。通过将类对象指定给常量,可以为类命名
如果给定一个块,它将被传递给类对象,并使用class\u eval
在该类的上下文中计算该块
您对模块的命名类似于
sue=Boy.new
,因此我将其更改为适合其传统。我相信你不会介意的
module MyModule
def foo
"method"
end
end
让我们首先收集一些基本信息:
Module.class #=> Class
Module.ancestors #=> [Module, Object, Kernel, BasicObject]
Module.methods.include? :new #=> true
Module.new #=> #<Module:0x000001022050c8>
它是类
的一个实例,只有一个您创建的实例方法(:foo
)。它没有祖先,因此不继承任何方法。重要的是,模块的实例没有方法:new
。因此,如果我们尝试调用它,结果是可预测的:
my_new_module = MyModule.new
#=> NoMethodError: undefined method `new' for MyModule:Module
方法#1`的故事结束
现在收集与第二种方法相关的信息:
my_new_instance = Class.new { include MyModule }.send :new
我已将变量my_new_class
的名称更改为my_new_实例
,原因很快就会显现出来。我们可以分两步编写,如下所示:
Class1 = Class.new { include MyModule }
Class1.instance_methods.include? :foo #=> true
Class1.methods.include? :new #=> true
Class1.method(:new).owner #=> Class
因此,我们确认Class1
构造正确,具有实例方法:foo
,并从类继承类方法:new
my_new_instance = Class1.new #=> #<Class1:0x00000101a1edc8>
my_new_instance = Class1.send :new #=> #<Class1:0x0000010204eab8>
my_new_instance.class #=> Class1
my_new_instance.is_a? Class #=> false
my_new_instance.foo # (prints) "method"
my_new_instance.send :foo # (prints) "method"
my_new_instance=Class1.new#=>#
我的新实例=Class1.send:new#=>#
my_new_instance.class#=>Class1
我的新例子是a吗?类#=>假
my_new_instance.foo#(打印)“方法”
my_new_instance.send:foo#(prints)“方法”
我们看到,my_new_实例
确实是Class1
的一个实例(它可以通过所示的任何一种方法创建),并以所示的两种方式调用:foo
。您对模块的命名类似于sue=Boy.new
,因此我对它进行了更改,以适应它的传统。我相信你不会介意的
module MyModule
def foo
"method"
end
end
让我们首先收集一些基本信息:
Module.class #=> Class
Module.ancestors #=> [Module, Object, Kernel, BasicObject]
Module.methods.include? :new #=> true
Module.new #=> #<Module:0x000001022050c8>
它是类
的一个实例,只有一个您创建的实例方法(:foo
)。它没有祖先,因此不继承任何方法。重要的是,模块的实例没有方法:new
。因此,如果我们尝试调用它,结果是可预测的:
my_new_module = MyModule.new
#=> NoMethodError: undefined method `new' for MyModule:Module
方法#1`的故事结束
现在收集与第二种方法相关的信息:
my_new_instance = Class.new { include MyModule }.send :new
我已将变量my_new_class
的名称更改为my_new_实例
,原因很快就会显现出来。我们可以分两步编写,如下所示:
Class1 = Class.new { include MyModule }
Class1.instance_methods.include? :foo #=> true
Class1.methods.include? :new #=> true
Class1.method(:new).owner #=> Class
因此,我们确认Class1
构造正确,具有实例方法:foo
,并从类继承类方法:new
my_new_instance = Class1.new #=> #<Class1:0x00000101a1edc8>
my_new_instance = Class1.send :new #=> #<Class1:0x0000010204eab8>
my_new_instance.class #=> Class1
my_new_instance.is_a? Class #=> false
my_new_instance.foo # (prints) "method"
my_new_instance.send :foo # (prints) "method"
my_new_instance=Class1.new#=>#
我的新实例=Class1.send:new#=>#
my_new_instance.class#=>Class1
我的新例子是a吗?类#=>假
my_new_instance.foo#(打印)“方法”
my_new_instance.send:foo#(prints)“方法”
我们看到,mynew\u实例
确实是Class1
的一个实例(可以通过所示的任何一种方法创建),并以所示的两种方式调用:foo
。您不能执行第二个示例:TypeError:错误的参数类型类(预期模块)
。关键字include
需要一个模块,看起来是。输入错误。我的意思是只需要一个模块。很好的捕获。编辑后,您无法执行第一个示例(NoMethodError:MyClass:Module的未定义方法“new”)。无法执行第二个示例:TypeError:Error参数类型类(预期模块)
。关键字include
需要一个模块,看起来是。输入错误。我的意思是只需要一个模块。很好的捕获。编辑后,您无法执行第一个示例(NoMethodError:undefined method'new',for MyClass:Module
)。