Rubyの下記のソースの意図がわかりません。


(class<<self;self;end).module_eval do
 define_method(:usage) do |msg|
  puts op.to_s
  puts "error: #{msg}" if msg
  exit 1
 end
end

引用元:
https://github.com/fluent/fluentd/blob/master/lib/fluent/command/cat.rb

グローバルに使える関数usageを定義しているのかなぁと推測していますが、
何故定義できるのかよく理解できていません。

質問は、
1. (class<<self;self;end).module_evalは何をしているのでしょうか
2. トップレベルにメソッド定義を記述するのと何が違うのでしょうか

教えて頂けないでしょうか。

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2013/08/16 03:51:37
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:nuna No.1

回答回数32ベストアンサー獲得回数11

ポイント100pt

>1. (class<<self;self;end).module_evalは何をしているのでしょうか

このコードはトップレベルで実行されていますので、selfはmainオブジェクトです。
よって (class<<self;self;end) で main オブジェクトの特異クラスを得ています。

mainはObjectクラスのインスタンスですので、ほかのオブジェクトに影響を与えず、
mainにメソッド定義をするためにこうしているのでしょう。

>2. トップレベルにメソッド定義を記述するのと何が違うのでしょうか

ローカル変数 op を参照するためにdefine_methodを使っているのだと思います。
個人的にはやりたい事に対して手段が過剰な気がしますが……

def でメソッド定義をすると、メソッド内から外側のローカル変数は参照できません。
一方ブロックはそれが可能です。

id:heboprog

ありがとうございます。とても納得しました。

2013/08/16 03:51:19

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません