我正在写一个ruby DSL,它将用于代码生成一些 objective - c++ 函数。我希望每个函数的名称从其ruby DSL源文件的名称派生。
例如,给定这个源文件clusterOptions.rb
:
require './vMATCodeMonkey'
VMATCodeMonkey.new(:print).options_processor <<EOS
-cutoff: flag: set('useCutoff', true), arg: vector('double')
-depth: flag: set('useInconsistent', true), arg: scalar('double', default: 2.0)
-maxclust: flag: set('useCutoff', false), arg: vector('index')
EOS
当计算VMATCodeMonkey.new(:print)
表达式时,我将理想地以某种方式像新对象一样捕获clusterOptions.rb
源文件名。这可能吗?
[虽然我怀疑不可能完全按照我所描述的那样做,但我还是询问,因为我不止一次对ruby的模糊功能感到惊讶]
EDIT:我知道__FILE__
;我正在寻找的是一些以DSL为中心的方法来捕获DSL源文件的名称,而不需要在DSL源中明确提及__FILE__
。嗯,现在我试图解释它,也许从类initialize
方法爬上堆栈跟踪?
感谢tadman,这是我的VMATCodeMonkey#initialize
方法:
def initialize(out_opt = :print)
@caller_file = caller(1)[0].split(':')[0]
case out_opt
when :pbcopy
@out = IO.popen('pbcopy', 'w')
when :print
@out = $stdout
else
raise ArgumentError, "#{out_opt} is not an option!"
end
@out.puts "// vMATCodeMonkey's work; do not edit by hand!nn"
initialize_options_processor
end
下面是它捕获的内容:
@caller_file = "/Users/Shared/Source/vMAT/ruby/clusterOptions.rb"
正在评估的源文件的完整路径存储在__FILE__
中。如果只需要文件名,可以使用:
File.basename(__FILE__)
__FILE__
常量在C、c++、Perl和Python等语言中是通用的。
如果您需要知道是哪个文件调用了当前运行的例程,可以这样做:
caller(1)[0].split(':')[0]
这假定您的文件名中没有:
,但在大多数情况下,这应该是一个相当安全的假设。您还需要在库的入口点调用它。如果它是堆栈中更深的方法,测试caller(2)
等等。