使用caller
あなたは、コールスタックの最上部にどれだけ近いかを判断するには:一例として、我々は2を使用することができます
---------------------------------------------------------- Kernel#caller
caller(start=1) => array
------------------------------------------------------------------------
Returns the current execution stack---an array containing strings
in the form ``_file:line_'' or ``_file:line: in `method'_''. The
optional _start_ parameter determines the number of initial stack
entries to omit from the result.
def a(skip)
caller(skip)
end
def b(skip)
a(skip)
end
def c(skip)
b(skip)
end
c(0) #=> ["prog:2:in `a'", "prog:5:in `b'", "prog:8:in `c'", "prog:10"]
c(1) #=> ["prog:5:in `b'", "prog:8:in `c'", "prog:11"]
c(2) #=> ["prog:8:in `c'", "prog:12"]
c(3) #=> ["prog:13"]
これは、今scriptize
# scriptize.rb
def scriptize
yield ARGV if caller.size == 1
end
ため、この定義を与えますお互いに必要なライブラリ/実行可能ファイル
# libexA.rb
require 'scriptize'
require 'libexB'
puts "in A, caller = #{caller.inspect}"
if __FILE__ == $0
puts "A is the main script file"
end
scriptize { |args| puts "A was called with #{args.inspect}" }
# libexB.rb
require 'scriptize'
require 'libexA'
puts "in B, caller = #{caller.inspect}"
if __FILE__ == $0
puts "B is the main script file"
end
scriptize { |args| puts "B was called with #{args.inspect}" }
だから我々ru nは、コマンドラインから:
% ruby libexA.rb 1 2 3 4
in A, caller = ["./libexB.rb:2:in `require'", "./libexB.rb:2", "libexA.rb:2:in `require'", "libexA.rb:2"]
in B, caller = ["libexA.rb:2:in `require'", "libexA.rb:2"]
in A, caller = []
A is the main script file
A was called with ["1", "2", "3", "4"]
% ruby libexB.rb 4 3 2 1
in B, caller = ["./libexA.rb:2:in `require'", "./libexA.rb:2", "libexB.rb:2:in `require'", "libexB.rb:2"]
in A, caller = ["libexB.rb:2:in `require'", "libexB.rb:2"]
in B, caller = []
B is the main script file
B was called with ["4", "3", "2", "1"]
だから、これはscriptizeを使用しての等価性を示し、if $0 == __FILE__
しかし、それを考慮してください。
if $0 == __FILE__ ... end
を簡単に読ん他人が認識し、標準ルビーイディオムですあなたのコード
require 'scriptize'; scriptize { |args| ... }
は、同じ効果のためのより多くのタイピングです。
これが本当に価値があるためには、スクリプト化の本文にいくつかのファイルの初期化、引数の解析などの共通性が必要です。十分に複雑になると、クラスをスクリプト化して、インスタンス化してメインのスクリプト本体を実行したり、名前が何であるかに応じてクラスの1つを動的に必要とするメインスクリプトを作成したりすることができます。
を実行することができます。ファイルの末尾にある1行ではなぜそれを行えないのでしょうか?何か 'Foo.new.run(* ARGV)if __FILE__ == $ 0'のようなもの – kch
Kernel#callerを使った解決策があるかもしれません。あなたが私にそれを詳しく説明してもらいたいかどうか教えてください。 – kch