2014-04-22 43 views
4

是否有可能獲取需要在Ruby中的另一個文件的文件的位置?獲取父需求文件的路徑,紅寶石

我有一個項目,我產生了一些進程,我希望能夠在代碼中確定哪個文件是所需文件的父文件。調試時這很好。

例子:

#initial.rb: 
require "./my_file.rb" 
fork do 
    require "./my_file2.rb" 
end 

-

#my_file.rb: 

puts "Required from file: #{?????}" 

-

#my_file2.rb: 

require "./my_file.rb" 

我希望得到的東西,如:

#=> Required from file: /path/to/initial.rb 
#=> Required from file: /path/to/my_file2.rb 
+1

嘗試'$ 0' ..在你想要的文件中。閱讀[this](http://ruby-doc.org/docs/keywords/1.9/Object.html#method-i-__FILE__)。我現在不能測試,但是試試'puts「必須來自文件:#{$ 0}」' –

+0

這給了我'nil' – Automatico

+0

你應該使用'require_relative'而不是'require'./my_file.rb「'。無論解決方案是什麼,它也應該與'require_relative'一起工作。 – knut

回答

1

您不應該這樣做,但您可以從Kernel#caller檢查調用堆棧。你必須過濾掉require方法(特別是如果你使用任何覆蓋require的庫)。

alias :old_require_relative :require_relative 
def require_relative(arg) 
    #~ puts caller.map{|x| "\t#{x}"} 
    puts "%s requires %s" % [ caller.first.split(/:\d+/,2).first, arg] 
    old_require_relative arg 
end 
alias :old_require :require 
def require(arg) 
    #~ puts caller.map{|x| "\t#{x}"} 
    puts "%s requires %s" % [ caller.first.split(/:\d+/,2).first, arg] 
    old_require arg 
end 

與以下負載序列的測試測試場景:

+0

你能否解釋一下爲什麼我從來不應該這樣做?我想這不是一件普通的事情,但我在可能使用相同庫的子流程中進行錯誤日誌記錄,我需要將它們區分開來。我可以做PID事情,但它會嚴重地使事情複雜化,以記錄哪些進程開始於哪裏,並將這些事情聯繫起來,只是爲了弄清楚我的哪些子進程向某些庫提供了非法數據。 – Automatico

+0

如果您使用了'logger'或類似的gem,則可以將每個子進程的模式設置爲包含唯一標識符。然後你的共享庫可以'def logger; Logging.logger [自]; end'和'logger.error('message')'等等。或者你可以讓你的共享庫帶一個參數或其他東西。 –

2

基於Jacobs answer我這個重新定義的require_relativerequire結束

test.rb 
+- test1.rb 
    +- test1_a.rb 
+ test2.rb 

以下呼叫

require './test1' 
require './test2' 

require_relative 'test1' 
require_relative 'test2' 

結果:

test.rb requires ./test1 
C:/Temp/test1.rb requires test1_a 
test.rb requires ./test2 

你也可以包括在輸出的要求就行了。

+0

我喜歡這種方法,但正如我在@JacobLukas [回覆](http://stackoverflow.com/a/23225708/741850)中所提到的那樣,在涉及多個進程時會遇到問題。我將不得不復制這幾個地方。我還需要一個變量中的字符串可以訪問代碼中的其他地方,但這很容易。 – Automatico