Ruby: `new`を使わずにクラスのinitializeを実行してみる

やってみたらできました(Ruby 2.6.3)。業務では使う意味がないというか使わないでください。

class Foo
  def initialize
    @a = 1
    @b = 2
  end

  def inspect
    puts @a
    puts @b
  end
end

簡単のため、上のinitializeには引数もブロックも渡していません。

以下は普通にnewした場合です。

» a = Foo.new
1
2
» a.inspect
1
2

allocatetapsendでやる

  • Class#allocateを使うと、initializeを呼び出さずにインスタンスを生成できる
  • initializeメソッドはprivateなので、send(:initialize)で無理やり呼び出す
  • tapを使ってsend(:initialize)のブロックをねじ込む
» a = Foo.allocate.tap {|i| i.send(:initialize) }
1
2
#»
» a.class
#» Foo
» a.inspect
1
2

参考: instance method Class#allocate (Ruby 2.6.0)
参考: instance method Object#tap (Ruby 2.6.0)
参考: instance method Object#__send__ (Ruby 2.6.0)

Rubyのinitializeメソッドは特殊

Rubyのinitializeメソッドは、普通のインスタンスメソッドのような形をしていながら、例外的にprivateメソッドにされます。

» Foo.initialize
NoMethodError: private method `initialize' called for Foo:Class
from (pry):14:in `__pry__'

参考: instance method Object\#initialize (Ruby 2.6.0)

initialize という名前のメソッドは自動的に private に設定されます。
docs.ruby-lang.orgより

おたより発掘

Ruby: `new`を使わずにクラスのinitializeを実行してみる

Foo.allocate.instance_eval { initialize } と言う手もありますな

2019/07/04 19:09

ありがとうございます!pryではうまく動かなかったのですが、ファイルにしたら動きました。

ファイルの場合

# not_new.rb

#!/usr/bin/env ruby -
# encoding: UTF-8

class Foo
  def initialize
    @a = 1
    @b = 2
  end

  def inspect
    puts @a
    puts @b
  end
end

p a = Foo.new
p a.inspect
$ ruby not_new.rb
1
2

1
2

(参考)pryの場合

» class Foo
»   def initialize
»     @a = 1
»     @b = 2
»   end
»
»   def inspect
»     puts @a
»     puts @b
»   end
» end
#» :inspect
» foo = Foo.allocate.instance_eval { initialize }
#» 2
» foo.inspect
#» "2"

関連記事

Rubyのオブジェクト作成方法を改変する(翻訳)

デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ 開発エンジニア積極採用中です! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

Twitter: @hachi8833、GitHub: @hachi8833 コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。 これまでにRuby on Rails チュートリアル第2版の監修および半分程度を翻訳、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れて更新翻訳中。 かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。 実は最近Go言語が好きで、Goで書かれたRubyライクなGoby言語のメンテナーでもある。 仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。

hachi8833の書いた記事

夏のTechRachoフェア2019

週刊Railsウォッチ

インフラ

ActiveSupport探訪シリーズ