簡體   English   中英

為什么我們不能在Ruby中初始化TrueClass

[英]Why can't we initialize TrueClass in Ruby

為什么我們TrueClass在Ruby中初始化TrueClass 我得到這個:

TrueClass.new # => NoMethodError: undefined method `new' for TrueClass:Class

但是, TrueClass superclassObject

同樣,我們無法初始化NilClassFalseClass

我只是想知道即使這是Object的子類,這也是可行的。 如果我們想編寫一個與此類似的類,我們如何實現呢?

我只是想知道即使這是Object的子類,這也是可行的。 如果我們想編寫一個與此類似的類,我們如何實現呢?

您可以使用undef關鍵字undef定義繼承的方法。 由於new是一個類方法,因此您必須在該類的singleton類內使用undef 看起來像這樣:

class <<MyClass
  undef new
end
MyClass.new # NoMethodError: undefined method `new' for MyClass:Class

我只是想知道即使這是Object的子類,這也是可行的。

它通過取消定義allocatenew 這是相應的C代碼

rb_undef_alloc_func(rb_cTrueClass);
rb_undef_method(CLASS_OF(rb_cTrueClass), "new");

您可以通過undef_method在Ruby中獲得類似的結果:

class FooClass
  ::FOO = new    # <- this will be the only Foo instance
  class << self
    undef_method :allocate
    undef_method :new
  end
end

FooClass.new      #=> NoMethodError: undefined method `new' for FooClass:Class
FooClass.allocate #=> NoMethodError: undefined method `allocate' for FooClass:Class

FOO #=> #<FooClass:0x007fddc284c478>

“相似”,因為TrueClass.allocate實際上不會引發NoMethodError ,但會TypeError

TrueClass.allocate #=> TypeError: allocator undefined for TrueClass

不幸的是,在Ruby中無法使用rb_undef_alloc_func 我們可以通過覆蓋allocate來模仿行為:

class FooClass
  class << self
    def allocate
      raise TypeError, "allocator undefined for #{self}"
    end
    undef_method :new
  end
end

FooClass.allocate  #=> TypeError: allocator undefined for FooClass

不知道哪種方法更清潔。


上述更改使您無法通過new創建實例,但是還有其他方法:

FOO       #=> #<FooClass:0x007fddc284c478>

FOO.dup   #=> #<FooClass:0x007fad721122c8>
FOO.clone #=> #<FooClass:0x007f83bc157ba0>

Marshal.load(Marshal.dump(FOO)) #=> #<FooClass:0x007f83bc13e330>

為了解決所有這些特殊情況,Ruby的stdlib提供了Singleton模塊:

require 'singleton'

class Foo
  include Singleton
end

它通過allocatenew私有方法來工作:(除其他更改外

Foo.new      #=> NoMethodError: private method `new' called for Foo:Class
Foo.allocate #=> NoMethodError: private method `new' called for

並且它添加了一個instance ,該實例返回一個實例:(或實例,只有一個)

Foo.instance #=> #<Foo:0x007fdca11117e8>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM