我如何在ruby中从超类中的方法访问子类中的当前__FILE__

nwnhqdif  于 2022-12-12  发布在  Ruby
关注(0)|答案(4)|浏览(111)

我希望为日志设置一个默认路径,相对于使用日志的文件的路径,如下所示:

# /path/to/lib/bar.rb
class Bar
  def settings_file_path
    File.dirname(File.expand_path(__FILE__))
  end
end

# /path/to/app/models/foo.rb
class Foo < Bar
end

Foo.new.settings_file_path

理想输出:

# => /path/to/app/models

实际产量:

# => /path/to/lib

因为FILE引用的是写入它的文件,而不是调用它的文件,所以它返回的是bar.rb文件,但我希望这样的代码返回foo.rb文件的路径,即使该方法是在Bar中定义的。
有人有什么建议吗?

z9ju0rcb

z9ju0rcb1#

最简单的方法如下:

# foo.rb
class Foo
  def self.my_file
    @my_file
  end
end

# bar.rb
class Bar < Foo
  @my_file = __FILE__
end

# main.rb
require_relative 'foo'
require_relative 'bar'
p Bar.my_file
#=> "/Users/phrogz/Desktop/bar.rb"

但是,您可以在self.inherited挂接中解析调用者,如下所示:

# foo.rb
class Foo
  class << self
    attr_accessor :_file
  end
  def self.inherited( k )
    k._file = caller.first[/^[^:]+/]
  end
end

# bar.rb
class Bar < Foo
end

# main.rb
require_relative 'foo'
require_relative 'bar'

p Bar._file
#=> "/Users/phrogz/Desktop/bar.rb"

我不确定解析的健壮性和可移植性如何;我建议你试试。

  • 注意:我的Bar继承自Foo,这与您的问题正好相反。请不要被我们的设置差异所迷惑。*
ljsrvy3e

ljsrvy3e2#

caller.first[/^[^:]+/]在Windows上不起作用,因为绝对路径看起来像$DRIVE:$PATH(例如C:/Windows/system32
使用caller_locations.first.absolute_path代替caller.first[/^[^:]+/]

4c8rllxm

4c8rllxm3#

Ruby 2.7添加了模块#const_source_location

const_source_location(:Foo)
wh6knrhe

wh6knrhe4#

使用**$0**代替__ FILE__:)

相关问题