问题
I thought all classes in Ruby can be instantiated. What's preventing Integer
class from being instantiated with new
method?
Integer.new
# => NoMethodError: undefined method `new' for Integer:Class
回答1:
There are a few of those. Besides Integer
, Float
, and Symbol
, you can't create a new instance of TrueClass
, FalseClass
and NilClass
too.
These classes (and their respective instances) are all special in Ruby and are handled in a specific way internally.
With small Integers for example, Ruby implicitly handles those. Instead of creating a new "actual" Ruby object for each integer number (which would be hugely wasteful), Ruby stores those as only their numeric value represented by the object_id. Thus, what you observe in Ruby as an instance of the Integer class is actually a single value im memory (more or less). To be able to pull this off, Ruby reserves all odd object_id
s for integer values. Thus, the number 1
has the object_id
of 3
, the number 2
has the object_id
of 5
and so on...
Due to this special handling by the Ruby language itself, you can't create a new Integer instance. Now given that Integers themselves are always immutable (that is, they can't be changed) they are only defined by their numeric value in the first place.
(Note that this only works for small integers. For larger integers, depending on whether you are running on a 32 bit or 64 bit architecture, Ruby will still internally create real objects if the integer number can't fit into the scheme described above. This is however handled internally by Ruby and is basically an implementation detail of the language itself.)
回答2:
You can't allocate heap objects of an Integer in Ruby. In Ruby Integers are immediates which means you cannot have an instantiated version of the object. Since you can’t allocate them, you can’t create a subclass and allocate instances of the subclass.
来源:https://stackoverflow.com/questions/45693111/why-cant-i-instantiate-integer-class-in-ruby