2017-05-28 83 views
2

如何以編程方式獲取定義當前正在執行的代碼的類?我需要找到上課的時候控制流過由於super()多種方法定義運行:Ruby:獲取定義當前正在執行的代碼的類

class A 
    def foo 
    puts(get_current_class) 
    end 
end 

class B < A 
    def foo 
    puts(get_current_class) 
    super 
    end 
end 

class C < B 
    def foo 
    puts(get_current_class) 
    super 
    end 
end 

C.new.foo 
# => C 
# => B 
# => A 

我知道怎麼弄的方法名稱(使用__callee__caller_locations__method__);但是班級呢?

回答

1

由於Ruby類也模塊,這可能是與Module#nesting實現:

class A 
    def foo 
    puts(Module.nesting.first) 
    end 
end 

class B < A 
    def foo 
    puts(Module.nesting.first) 
    super 
    end 
end 

class C < B 
    def foo 
    puts(Module.nesting.first) 
    super 
    end 
end 

C.new.foo 
# => C 
# => B 
# => A 

或者,如果我們的目標是建立一個列表,它的方法可以通過對象的祖先鏈被調用,然後你可以使用Method#ownerMethod#super_method(可since ruby version 2.2.0):

c = C.new 
c.method(:foo).owner # => C 
c.method(:foo).super_method.owner # => B 
c.method(:foo).super_method.super_method.owner # => A 
c.method(:foo).super_method.super_method.super_method # => nil 

作爲一個快速現成的,袖口實現以編程方式打印所有類的話,怎麼樣:

c = C.new 
method = c.method(:foo) 
while(method) 
    puts m.owner 
    method = method.super_method 
end 
# => C 
# => B 
# => A 

(但是,不能保證所有的這些方法實際上將被調用 - 因爲這是在運行時通過super確定)

+0

但是,我甚至不能遠程想象的任何情況,其中一個實際上需要這個。我的意思是,如果你在'B'類中寫了一個'foo'方法,那麼你知道你在'B'類。它就在屏幕的頂部。 –

+0

是的,我同意......我幾乎可以肯定地只是寫代碼中的'puts「從類B」'調用foo(),而不是像上面那樣「編程」。不過,如果您想快速將調試語句放置在多個地方,也許這會很有用。 –

相關問題