我想获取带有继承函数的ruby类的文件名。这样的事情:
# a.rb
class A
def get_file()
__FILE__
end
end
# b.rb
class B < A
end
# c.rb
myobj = B.new()
puts myobj.get_file()
b.rb是预期的,但我有a.rb。
我有很多像B这样的类,所以我不想为继承了A的每个类添加一个函数。我想在A类中添加一个泛型方法来获取好的文件。 有人可以帮帮我吗?
埃里克
答案 0 :(得分:1)
这就是我的目录:
-home
|-kirti
|-workpspace
|-Ruby
|- a.rb
|- b.rb
|- c.rb
以下是文件内容:
<强> a.rb 强>
class A
def get_file()
[__FILE__,$0]
end
end
<强> b.rb 强>
require_relative 'a.rb'
class B < A
end
<强> c.rb 强>
require_relative 'b.rb'
myobj = B.new()
puts myobj.get_file()
现在我正在运行代码:
(arup~>Ruby)$ ruby c.rb
/home/kirti/workspace/Ruby/a.rb
c.rb
(arup~>Ruby)$
现在让我首先提出__FILE__
当前正在执行的文件的名称,包括相对于启动应用程序的目录的路径(或当前目录,如果已更改)。 当前文件在某些情况下与正在运行的应用程序的启动文件不同,后者在全局变量
$0
中可用。< / em>的
从文档中可以清楚地看出__FILE__
是当前文件位置,它与启动文件$0
不同。所以 c.rb 是您的启动文件,但当前文件是 /home/kirti/workspace/Ruby/a.rb 。
基本上,魔术变量__FILE__
的值是在加载文件时创建和存储(但从未更新)的相对路径。现在,在您的情况下,您将其保存在文件a.rb
内,因此它包含 /home/kirti/workspace/Ruby/a.rb 。
class B < A ;end
,表示您要将A
添加到类B
的祖先链中。这并不意味着将A
中的方法添加到B
。 get_file
方法仍在cass A
中。您的对象myobj
将首先在类get_file
内搜索方法B
,如果未找到,则将其搜索到祖先链中的类和模块中。现在get_file
位于班级A
内,A
位于文件a.rb
中,因此__FILE__
的值应设置为 { {1}} ,第一次加载 a.rb 时。现在/home/kirti/workspace/Ruby/a.rb
将课程require_relative 'a.rb'
提供给文件 b.rb ,但A
的值不会更新。
希望有所帮助!
答案 1 :(得分:-2)
感谢Arup和Jesse帮助我。我已经找到了他们的响应解决方案。
这是我的解决方案:
<强> a.rb 强>
class A
# Called from b.rb at `class A < B`. `subclass` is the Class object B.
# This method makes sure every subclass (class B, class C...)
# has #get_file defined correctly for instances of the subclass.
def self.inherited (subclass)
subclass.instance_eval do
# This array contains strings like "/path/to/a.rb:3:in `instance_eval'".
strings_ary = caller
# We look for the first string containing "(root)".
require_index = strings_ary.index {|x| x.include?("(root)") }
require_string = strings_ary[require_index]
# We use a regex to extract the filepath from require_string.
filepath = require_string[/^(.*):\d+:in `\(root\)'/, 1]
# This defines the method #get_file for instances of `subclass`.
define_method(:get_file) { filepath }
end
end
# For instances of class A only, we use the __FILE__ keyword.
# This method is overwritten by the #get_file method defined above.
def get_file
__FILE__
end
end
<强> b.rb 强>
class B < A
end
<强> c.rb 强>
require_relative 'a'
require_relative 'b'
p A.new.get_file
p B.new.get_file
c.rb的输出
"<path>/Test/lib/tmp/a.rb"
"<path>/Test/lib/tmp/b.rb"
@Jesse =&gt;我不知道为什么你的解决方案在我的桌面上不起作用。关键字 top(required)不存在,我已将(root)替换为索引搜索而不是rindex。我在ruby 1.7.3上。我的来电者的输出是:
<path>/Test/lib/tmp/a.rb:6:in `instance_eval'
<path>/Test/lib/tmp/a.rb:6:in `inherited'
<path>/Test/lib/tmp/b.rb:4:in `(root)'
<path>/jruby-1.7.3/lib/ruby/shared/rubygems/custom_require.rb:1:in `require'
<path>/jruby-1.7.3/lib/ruby/shared/rubygems/custom_require.rb:1:in `(root)'
<path>/jruby-1.7.3/lib/ruby/shared/rubygems/custom_require.rb:36:in `require'
<path>\Test\lib\tmp\c.rb:5:in `(root)'
再次感谢您的帮助。
埃里克