在ruby DSL实现中捕获spec文件名?

时间:2013-04-24 15:12:53

标签: ruby dsl objective-c++ vmat

我正在编写 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源文件名的新对象。这可能吗?

如果(我怀疑)它不是,那么是否有一个很好的习惯用于实现这个功能[例如使源文件名有效地成为DSL中捕获的规范的一部分]在 ruby​​ 中?

[虽然我怀疑但我不可能完全按照我的描述去做,但无论如何要求,因为我对 ruby​​感到惊讶

编辑:我知道__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!\n\n"
    initialize_options_processor
  end

以下是它捕获的内容:

@caller_file = "/Users/Shared/Source/vMAT/ruby/clusterOptions.rb"

1 个答案:

答案 0 :(得分:1)

正在评估的源文件的完整路径存储在__FILE__中。如果你只想要文件名,你可以使用:

File.basename(__FILE__)

__FILE__常量对于C,C ++,Perl和Python等是通用的。

如果您需要知道哪个文件调用了当前正在运行的例程,这可能有效:

caller(1)[0].split(':')[0]

这假设您的文件名中没有:,但在大多数情况下,这应该是一个相当安全的假设。您还需要在进入库的入口处调用它。如果它是堆栈中更深层次的方法,请测试caller(2),依此类推。