タイトルの通りですが、そのようになるそうです。
あー、先日下呂温泉で開催されたSWESTにて、Matzさんを交えて徹夜(!)でmrubyについて協議した結果です。思ったほどRAMが大きいマイコンばかりでは無く小さい物もふつーにあるので、mruby本体もちいさくありたいとのリバランスです。
— mrubyc-dev-jp (@mrubyc_dev_jp) October 10, 2018
とりあえず、ブログを書いて状況や対処法などを残しときます。
状況
このコミット以降、主に Kernel/Module
のメソッドとして実装されたメタプログラミング機能を使いたい場合、 mruby-metaprog という同梱されるmgemを明示的に依存に追加する必要が出て来ます。
どれが対象で、どれが非対象かは当該コミットと、後のコミット (https://github.com/mruby/mruby/commit/b80e0ef7428b613a682da4d2a251c8beb24d6dd2) のコメントの通りです。
mruby-metaprog に移動したメソッド
* Kernel module global_variables, local_variables, singleton_class, instance_variables, instance_variables_defined?, instance_variable_get, instance_variable_set, methods, private_methods, public_methods, protected_methods, singleton_methods, define_singleton_methods, send * Module class class_variables, class_variables_defined?, class_variable_get, class_variable_set, remove_class_variable, included_modules, instance_methods, remove_method, method_removed, constants * Module class methods constants, nesting
vanilla mruby(まったくmgemを含んでいないmrubyをこう呼ぶことにした)に残っているメソッド
* Module class alias_method, undef_method, ancestors, const_defined?, const_get, const_set, remove_const, method_defined?, define_method * Toplevel object define_method
ちなみに Object#__send__
もvanilla mrubyに残留しているようです。
で、このコミットは、 mruby 1.4.1 より 後 となります。
起こる問題
メタプログラミング機能を使ったmgemをこのコミット以降のmrubyで利用する場合、 mrbgem.rake
に以下の一行を追加する必要があります(default.gembox
にも含まれます)。
MRuby::Gem::Specification.new('mruby-sample') do |spec| spec.license = 'MIT' spec.authors = 'Uchio Kondo' # ... # <= here! spec.add_dependency 'mruby-metaprog', core: 'mruby-metaprog' end
ここで問題があるのですが、このコミットが入る以前のmruby(最後のリリースである1.4.1含みます)でビルドする場合、このmgemは当然mruby同梱mgemではないのでビルドできないです。こういうエラーになります。
Can't find /home/travis/build/haconiwa/mruby-process-sys/mruby/mrbgems/mruby-metaprog/mrbgem.rake
ではどうすれば... というのは難しいところですが、一つの策として:
という判定を行うことは可能です。ダックタイピングっぽいですね...。なのでそのままそういう分岐をすれば問題なく通るようになります。
MRuby::Gem::Specification.new('mruby-sample') do |spec| # ... if File.exist? "#{MRUBY_ROOT}/mrbgems/mruby-metaprog" spec.add_dependency 'mruby-metaprog', core: 'mruby-metaprog' end end
実際の変更例はこちら:
ということで、 undefined method 'send' (NoMethodError)
(検索対応のためエラーメッセージをそのまま書いときます)のようなエラーで悩まされたら、metaprogの依存についての対応をしてみてくださいませ。
Enjoy~