search
LoginSignup
20

More than 1 year has passed since last update.

posted at

updated at

Organization

Rubyにて一部newメソッドが機能しないクラスが存在する

背景

社内でオブジェクト指向を教えている時、以下は同じ意味ということをインターン生に教えた。

s = ''
s = String.new

しかしIntegerクラスに対して上記と同じことを試したら例外が返ってきた。

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

なぜか。

前提知識

  • Rubyにおけるオブジェクトは、特異メソッドである new を使用することで生成することができる
  • Rubyにおいてnewでオブジェクトが生成されるクラスとされないクラスが存在する
  • オブジェクトにはそれぞれ object_id (=参照するメモリ) を持っている

newを実行するとオブジェクトが生成できるRubyクラス

String

String.new
#=> ''

Array

Array.new
#=> []

Hash

Hash.new
#=> {}

newを実行すると例外が返ってくるRubyクラス

Integer

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

Float

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

TrueClass / FalseClass

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

Symbol

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

オブジェクトはそれぞれ object_id を持っている

Stringの場合

同じ文字列だが、object_idは異なる値が返ってくる

s = 'test'
p = 'test'

s.object_id
#=> 70189307859540
p.object_id
#=> 70189307841860

Integerの場合

同じ数値かつ同一のobject_idが返ってくる

s = 1
t = 1

s.object_id
#=> 3
t.object_id
#=> 3

まとめ

  • newを実行すると例外が返ってくるRubyクラスのオブジェクトは、1つしか持つことができない。だからobject_idが同一になり、newメソッドを使用することができない。
  • 逆に値が同一でも異なるobject_idが返却されるオブジェクトの場合、newメソッドで対象のClassからオブジェクトが生成することが可能。
  • オブジェクトを1つしか持つことができないメリットとして、メモリ消費を抑えることが挙げられる。文字列またはシンボルどちらでも可能な場合にシンボルが好ましいのはこの理由から。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
20