2014-12-23 35 views
9

Diciamo che ho un/lambda/block/metodo proc/etc in questo modo:Rubino: Come ottenere il valore di default di argomenti proc opzionali

2.1.2 :075 > procedure = Proc.new { |a, b=2, *c, &d| 42 } 
=> #<Proc:[email protected](irb):75> 

so di poter scoprire i nomi dei parametri con:

2.1.2 :080 > procedure.parameters 
=> [[:opt, :a], [:opt, :b], [:rest, :c], [:block, :d]] 

Ma come posso fare per ottenere il valore che un determinato parametro opzionale assumerebbe ove è non dato?


PS: Sì. So che questo è stato chiesto/risposto prima dello here, ma la soluzione precedente richiede l'uso della gemma merb, che in realtà è leggermente fuorviante. merb stesso dipendeva dalla gemma methopara (a meno che tu non sia su JRuby o MRI, cosa che non lo sono) che a sua volta ha fornito la funzione al momento della risposta alla domanda.

Purtroppo, al momento, methopara sembra essere abandonware. Inoltre, ha sempre supportato Ruby 1.9 (e nemmeno l'ultima versione), quindi sto cercando una soluzione che funzioni per le versioni attuali di ruby.

+2

Penso che sia quasi impossibile, devi prendere in considerazione che il cosiddetto valore "default" può essere qualsiasi tipo di codice eseguibile e sarà eseguito ogni volta che lo chiami. – hakcho

+0

@hakcho, cattura molto buona. (Ho completamente perso la cognizione di questo account e ho usato un approccio completamente diverso da quando ho postato questo.) Comunque, sarebbe bello avere accesso programmatico a quel valore (o routine, se è uno). – mikev

risposta

2

Supponendo che proc/lambda sia stato definito in un file, è possibile utilizzare il metodo source_location per trovare la posizione di tale file e il numero di riga in cui è stato definito.

2.2.0 (main):0 > OH_MY_PROC.source_location 
=> [ 
    [0] "sandbox/proc.rb", 
    [1] 1 
] 

con qualche aiuto da File.readlines possiamo fare una breve metodo che quando viene passato un proc/lambda può sputare fuori la linea di origine è stato definito su.

def view_def proc_lambda 
    location = proc_lambda.source_location 
    File.readlines(location[0])[location[1]-1] 
end 

In azione sembra qualcosa di simile

2.2.0 (main):0 > view_def OH_MY_PROC 
=> "OH_MY_PROC = Proc.new { |a, b=2, *c, &d| 42 }\n" 
2.2.0 (main):0 > view_def OH_MY_LAMBDA 
=> "OH_MY_LAMBDA = ->(a, b=2, *c, &d) { 42 }\n" 

Se si vuole fare lo stesso per i metodi diventa un po 'più complesso. In tal caso, ti consiglio di leggere questo post sul blog Pragmatic Studio: "View Source" On Ruby Methods

+0

potrebbe anche usare merb. source_location è eccezionale quando si salva un'eccezione e si desidera aprire proc nel proprio editor di testo. – Rivenfall

+0

@rivenfall Si prega di consultare il post originale. Merb non è un'opzione a causa di una dipendenza abbandonata. – mikev

+0

@brownmike Stavo cercando un modo per farlo senza analizzare il codice sorgente da solo, ma grazie per l'idea. In ogni caso, da allora sono andato in un modo diverso. – mikev