こんにちは。いつもお世話になっております。
目下、「パーフェクトRuby」を読んでいるのですが、同著の中の
サンプルコードで、動作を確認できないものがあったので、それについて、
質問させてください。
ついては、少し長いのですが、以下、同著第3章「制御構造/メソッド/組み込み関数」
P.114からの引用です。
▼===引用、ここから=============
eval とrequire_relative
Ruby には、文字列をRubyの式として評価する組み込み関数Kernel.#evalがあります
(詳しくは 7-3 eval を参照してください)。
lang
1eval "puts 1+2" # "3"と表示
Kernel.#require_relative は実行中のファイルパスを基準にrequireするのに便利ですが、
このKernel.#evalと組み合わせることはできません。
evalが評価する文字列の中でrequire_relativeを呼び出すと以下のような例外が発生し、
必ず失敗します。
lang
1eval <<EOS 2 require_relative 'foo' # LoadError: cannot infer basepath 3EOS
require_relative相当のことをしたい場合には、_FILE_ と組み合わせて以下の
ような方法でrequireすることができます。
このとき、_FILE_は eval の第3引数に渡したファイルパスを返します。
lang
1eval <<EOS, nil, '/path/to/fname.rb' 2 require File.expand_path('foo', File,dirname(_FILE_)) 3EOS
標準添付ライブラリのirbやerbも内部的にevalを使用しているため、require_relativeを
呼び出すことはできません。
▲===引用、ここまで=============
上記の説明で、例外「 LoadError: cannot infer basepath」を発生させて失敗する
サンプルコードは、自分の手元で再現できました。
再現できていないのは、後に出てくる
require_relative相当のことをしたい場合には、_FILE_ と組み合わせて以下の
ような方法でrequireすることができます。
のほうです。
まず、文中の「・・・requireすることができます。」というのは、
- evalで評価したい文字列となる、Rubyスクリプトを書く。
- それを別のrubyスクリプトから require で読み込んでevalに渡す。
- evalによって、requireで読み込まれたrubyスクリプトを評価する。
ということが出来るという意味と解釈しました。
(そもそも、この解釈が間違っているということでしたら、ぜひご指摘ください。)
これを検証するために以下のような、3行のinc.rb を作成しました。
(以降、[ykt68@sakura-vps]は自分の環境のプロンプトです。)
[ykt68@sakura-vps] pwd
/home/ykt68/perfectruby/ch03
[ykt68@sakura-vps] cat inc.rb
p = 10
q = 20
p + q*2
[ykt68@sakura-vps]
さらに、同じディレクトリ /home/ykt68/perfectruby/ch03 に、書籍の説明にある
コードに若干追加した、以下のような require_eval_test.rb を作成しました。
lang
1x = eval <<EOS, nil, '/home/ykt68/perfectruby/ch03/require_eval_test.rb' 2 require File.expand_path('inc', File.dirname(__FILE__)) 3EOS 4 5puts x
これを実行したときに、inc.rb の最後の式の評価結果である、50 と表示
されるものと思ったのですが、以下のように **true **と表示されました。
[ykt68@sakura-vps] cat require_eval_test.rb
x = eval <<EOS, nil, '/home/ykt68/perfectruby/ch03/require_eval_test.rb'
require File.expand_path('inc', File.dirname(_FILE_))
EOSputs x
[ykt68@sakura-vps] ruby require_eval_test.rb
true
そこで質問なのですが、
(1) 上記で表示された true は、require関数の戻り値と考えていますが、それで正しいでしょうか?
(2) 上記のrequire_eval_test.rbのどこかを若干修正すれば、inc.rb の最後の行の評価結果である、
50 が表示されるようにできますでしょうか?
もし出来るのでしたら、修正箇所を教えて頂けますと幸いです。
それとも、そもそも、元の書籍での説明が、この例で50と表示させるための
説明ではないのでしょうか?
質問は以上です。
よろしくお願い致します。
※1:使用しているrubyのバージョンは、以下です。
[ykt68@sakura-vps] ruby -v
ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-linux]
※2:なお引用文中、_FILE_の_は、記法の都合で全角アンダーバー1個で書いていますが、
本当は半角アンダーバー2個です。
ykt68拝
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/04/25 08:52