Rubyにおけるライブラリロード
Ruby のライブラリロード周辺を理解してなかったので、調査&実験メモです。*1
環境
OSX Mavericks rbenv 0.4.0 + ruby 2.1.2
ロードパス を調べる
$: でも $LOAD_PATHでも同じ。
$ ruby -e 'puts $:' /usr/local/Cellar/rbenv-gem-rehash/1.0.0 /Users/kotaroito/.rbenv/versions/2.1.2/lib/ruby/site_ruby/2.1.0 /Users/kotaroito/.rbenv/versions/2.1.2/lib/ruby/site_ruby/2.1.0/x86_64-darwin13.0 /Users/kotaroito/.rbenv/versions/2.1.2/lib/ruby/site_ruby /Users/kotaroito/.rbenv/versions/2.1.2/lib/ruby/vendor_ruby/2.1.0 /Users/kotaroito/.rbenv/versions/2.1.2/lib/ruby/vendor_ruby/2.1.0/x86_64-darwin13.0 /Users/kotaroito/.rbenv/versions/2.1.2/lib/ruby/vendor_ruby /Users/kotaroito/.rbenv/versions/2.1.2/lib/ruby/2.1.0 /Users/kotaroito/.rbenv/versions/2.1.2/lib/ruby/2.1.0/x86_64-darwin13.0 $ ruby -e 'puts $LOAD_PATH' /usr/local/Cellar/rbenv-gem-rehash/1.0.0 /Users/kotaroito/.rbenv/versions/2.1.2/lib/ruby/site_ruby/2.1.0 /Users/kotaroito/.rbenv/versions/2.1.2/lib/ruby/site_ruby/2.1.0/x86_64-darwin13.0 /Users/kotaroito/.rbenv/versions/2.1.2/lib/ruby/site_ruby /Users/kotaroito/.rbenv/versions/2.1.2/lib/ruby/vendor_ruby/2.1.0 /Users/kotaroito/.rbenv/versions/2.1.2/lib/ruby/vendor_ruby/2.1.0/x86_64-darwin13.0 /Users/kotaroito/.rbenv/versions/2.1.2/lib/ruby/vendor_ruby /Users/kotaroito/.rbenv/versions/2.1.2/lib/ruby/2.1.0 /Users/kotaroito/.rbenv/versions/2.1.2/lib/ruby/2.1.0/x86_64-darwin13.0
requireする
http://docs.ruby-lang.org/ja/2.1.0/method/Kernel/m/require.html
require 'uri' p URI.escape 'https://www.google.co.jp/search?q=るびー'
$: に格納されている PATHを順番に検索する。 手元では /Users/kotaroito/.rbenv/versions/2.1.2//lib/ruby/2.1.0/uri.rb をロードしていた。
ちなみに出力は
https://www.google.co.jp/search?q=%E3%82%8B%E3%81%B3%E3%83%BC
となる。
ここで 以下のファイルを用意して
# ./uri.rb class URI class << self def escape(url) 'whoops' end end end
require './uri' p URI.escape 'https://www.google.co.jp/search?q=るびー'
とすると 出力は
whoops
となる。
サブディレクトリを指定した時はどうなるのか?
# .foo/bar.rb class Buzz def initialize(name) @name = name end end
require './foo/bar' buzz = Buzz.new 'buzz' p buzz
ロードできた。 同時に、パスとクラス名は必ずしも一致してる必要はないこともわかった。
実際、標準で用意されている Queue クラスは require ‘thread’ して使うようだ。
ネストしたクラス
# ./foo.rb class Foo def hello 'foo' end end class Foo::Bar def hello 'bar' end end
require './foo' p Foo.new.hello # => ‘foo' p Foo::Bar.new.hello # => ‘bar'
と書ける。
# ./foo.rb class Foo def hello 'foo' end class Bar def hello 'bar' end end end
という書き方もできる。
module による名前空間
# ./foo.rb module Foo class Bar def hello 'bar' end end end
require './foo' p Foo::Bar.new.hello
moduleは名前空間を定義することにも使える。
まとめ
require, $LOADPATH, 名前空間について詳しくなりました。入門レベルとしてはここまでおさえておけば大丈夫な気がする(たぶん)。
See Also
Rails の autoload については、 Auto-loading lib files in Rails 4 - Stack Overflow に。