Class :: new和Class#new相同吗?

时间:2019-05-09 13:23:50

标签: ruby

Class的类方法版本为new,实例方法版本为new。但是因为ClassClass的实例,这不是使new的类方法版本成为new的实例方法版本吗?

当我看到以下内容

>> Class.new
=> #<Class:0x00007fca601fe898>

我认为Class对象是Class的实例,所以new是类Class的实例方法。而不是new是类Class的类方法。

2 个答案:

答案 0 :(得分:5)

Class::newClass#new不同。

  

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical"> <LinearLayout android:layout_width="50dp" android:layout_height="50dp" android:background="@android:color/transparent" android:orientation="vertical"> <ImageView android:id="@+id/imageView" android:layout_width="50dp" android:layout_height="50dp" android:layout_gravity="center" app:srcCompat="@drawable/ic_clock" /> </LinearLayout> <LinearLayout android:layout_width="300dp" android:layout_height="300dp" android:layout_margin="10dp" android:background="#000000" android:orientation="vertical"> </LinearLayout> </LinearLayout> 使用给定的名称创建一个新的匿名(未命名)类   超类。
  Class::new调用allocate创建一个新对象   类的类,然后调用该对象的initialize方法,并传递   args。

如果您单击上面的docs链接上的切换源,则可以看到它。

基本上Class.new是ruby中其他所有继承的默认初始化程序。
Class.new创建一个新的匿名类。

答案 1 :(得分:1)

Class::newClass#new相同。

就像其他类(newString.new等)中的Array.new方法一样,Class.new解析为Class#new。 Ruby类通常不提供自己的new类方法。我们可以通过替换Class#new来轻松确认这一点:

String.new #=> ""
Array.new  #=> []
Class.new  #=> #<Class:0x00007fef2517f5e0>

class Class
  def new(*args)
    "it's me, Class#new"
  end
end

String.new #=> "it's me, Class#new"
Array.new  #=> "it's me, Class#new"
Class.new  #=> "it's me, Class#new"

Class#new的原始实现通过调用接收者的allocate方法并调用该对象的initialize方法(传递参数)来创建新对象,例如:

class Class
  def new(*args, &block)
    obj = allocate
    obj.send(:initialize, *args, &block)
    obj
  end
end

因此Class#new是一个简单的template method –实际工作是由allocateinitialize完成的。

我们可以通过检查initialize来发现差异– Class的所有者是Class#initialize,而其实例的所有者是BasicObject

Class.instance_method(:initialize).owner
#=> Class

Class.new.instance_method(:initialize).owner
#=> BasicObject

混乱的原因是文档显示#initialize::new(这很方便,因为我们通常调用new,很少(如果有的话)直接调用initialize)。因此,如果您打开Class::new的文档并单击“ toogle源代码” ,则您正在查看Class#initialize(或rb_class_initialize的实现,在C中称为)

我知道唯一实际覆盖new类方法的类是Struct,即Struct::new

Struct.method(:new).owner        #=> #<Class:Struct>
Struct.method(:new).super_method #=> #<Method: Class#new>