2016-06-12 23 views
0

Ich hoffe, es ist möglich, die ursprüngliche Klasse/Methode/etc. einer bestimmten Rückkehr innerhalb einer anderen Methode zu bestimmen. Z.B .:Ruby - Bestimmung einer Rückkehr der Ausführung der Verfolgung/Herkunft

# Ruby 

class Stringify 
    def fancy(words) 
    return ">> #{words}" 
    end 

    def boring(words) 
    return "- #{words}" 
    end 
end 

class Yarnify 
    def fancy(words) 
    return ">> #{words}" 
    end 

    def boring(words) 
    return "- #{words}" 
    end 
end 

def printit(*args) 
    puts args 
end 

printit(Yarnify.new.boring("Hello")) 
printit(Stringify.new.fancy("Hey")) 
printit(Stringify.new.boring("Hi")) 
printit(Yarnify.new.fancy("Heyo")) 

# Output: 
"- Hello" 
">> Hey" 
"- Hi" 
">> Heyo" 

Wie zum Beispiel:

## Desired trace 
def printit(*args) 
    puts args 
    puts "Originated from #{args.what_called.method} within #{args.what_called.class}." 
end 

printit(Yarnify.new.fancy("This is a return!")) 

## Output 
">> This is a return!" 
"Originated from fancy within Yarnify." 

Der Inhalt des args scheint ausgeführt zu werden, bevor es in die printit Methode übergeben wird. Aber ich habe einen Anwendungsfall, in dem ich mehrere Eingänge, die identisch aussehen, dynamisch mische und daher die Quellklasse/Methode der args protokollieren muss. Die Rubydocs zu durchsuchen und mit öffentlichen/privaten Methoden auf args zu spielen war bisher nicht hilfreich. Wer weiß, ob es möglich ist?

Antwort

0

Ist caller was Sie suchen könnten? Es enthält einen Stack-Trace:

#!/usr/bin/env ruby 

require 'awesome_print' 

def foo 
    bar 
end 


def bar 
    baz 
end 


def baz 
    ap caller 
end 


foo 

=begin 
Outputs: 

[ 
    [0] "./caller.rb:11:in `bar'", 
    [1] "./caller.rb:6:in `foo'", 
    [2] "./caller.rb:20:in `<main>'" 
] 
=end 

Alternativ gibt es ein caller_locations Verfahren, das eine Reihe von Themen gibt :: Backtrace :: Location-Objekte (siehe http://ruby-doc.org/core-2.3.1/Thread/Backtrace/Location.html). Dadurch erhalten Sie mehr Kontrolle, da Sie Komponenten des Stack-Trace-Elements, z. B. Label, erhalten können.

+0

Vielen Dank für das Problem. Verwenden Sie Ihren Rat zu meinem obigen Beispiel: 'Pry (Haupt)> args.send: Anrufer => [" test.rb: 23: in "printit" ", " test.rb: 26: in '

' " ] ' –

+0

Identischer Ausdruck mit' caller_locations'. Ich sehe keine Möglichkeit, die Klasse/Methode durch diese spezielle Ablaufverfolgung in "Argumente" zu überführen, wenn außerhalb von Klassen und Methoden verwendet wird. –

+0

Entschuldigung, ich verstehe jetzt ... Sie haben recht, 'caller' wird Ihnen nicht helfen, weil das Argument ausgewertet wird, bevor sein erzeugter Wert an die Methode übergeben wird. Sie könnten stattdessen einen Block oder ein Lambda übergeben, so dass die Auswertung innerhalb der Methode zurückgestellt würde, aber das würde immer noch nicht wirklich helfen, wenn Sie nicht den Ruby-Byte-Code dieses Blocks oder Lambda überprüfen. –