2016-11-11 2 views
0

Название может быть нечетким.Как получить метод bb's вызывающий в методе bb, когда он вычитается в методе aa's block

здесь код

def self.aa(&block) 
    instance_eval &block 
    end 

    def self.bb 
    # i want to get aa info here 
    p caller[0] 
    end 

#shuriken is a module 
Shuriken.aa do 
    bb 
end 

я хочу, чтобы получить информацию о аа, когда ББ выполнить в аа блоке

, как решить эту проблему, или она может быть решена? благодаря;

+1

_ "я хочу, чтобы получить информацию о aa "_ - Не могли бы вы уточнить, что именно вы хотите в' bb'? И можете ли вы описать (на словах, а не код) то, что вы пытаетесь достичь? Это может помочь использовать менее абстрактный пример (например, с именами реальных методов, а не 'aa' и' bb') – Stefan

ответ

0

Чтобы префикс мой ответ: Это очень плохая практика. Не делайте этого в производственном коде.

Используя binding_of_caller драгоценный камень, мы оцениваем текущий метод два кадра вверх (первый кадр вверх является BasicObject#instance_eval, второй кадр вверх является Shuriken.aa):

require 'binding_of_caller' 

class Shuriken 
    def self.aa(&block) 
    instance_eval &block 
    end 

    def self.bb 
    the_aa = binding.of_caller(2).eval('method(__method__)') 
    puts the_aa 
    # => #<Method: Shuriken.aa> 
    end 
end 

Shuriken.aa do 
    bb 
end 
+0

, почему это очень плохая практика? – junk

+2

Обратите внимание, что 'binding_of_caller' - это действительно жестокий взлом. Он достигает внутренних деталей внутренней реализации механизма выполнения и разрывает информацию, к которой он не имеет доступа. Это означает, что он очень тесно связан с механизмом исполнения и даже с его конкретной версией. Например, он не работает на Opal, он не работает на MRuby, он не работает на IronRuby. В JRuby он работает только при использовании интерпретатора (чего почти никто не делает, поскольку производительность, получаемая от агрессивного оптимизирующего компилятора, является одной из основных причин, по которым люди сначала используют JRuby). ... –

+0

... На YARV он может быть поврежден в любой момент любым изменением внутренних элементов и, например, не работает на YARV 2.2 и 2.3, только 2.1 и ниже. О, я забыл: он также не работает на MagLev. И на MacRuby. И на RubyMotion. –