2011-09-12 18 views
17
>> string = '#{var}' 
=> "\#{var}" 

>> proc = Proc.new { |var| string } 
=> #<Proc:[email protected](pry):6> 

>> proc.call(123) 
=> "\#{var}" 

Non proprio quello che voglio. Le doppie virgolette intorno allo string danno come risultato l'ovvio undefined local variable.Come eseguire un'interpolazione di stringa "tardiva" in Ruby

+0

A cosa serve? Sembra una cosa molto bizzarra da voler fare. –

+1

Sì ... sono conosciuto per i miei bisogni bizzarri. È per queste due linee essere più DRY https://github.com/pjg/dotfiles/blob/5ae2e0c5a80be8b31d729d0739eb667fa99e5212/.pryrc#L46 –

+0

Penso che qualcosa del genere esista in Ruby Facets. –

risposta

17

Anche se questo è possibile, non è andare a lavorare come si intende qui, senza dover utilizzare eval, e generalmente è una cattiva idea se c'è un'alternativa. La buona notizia è che hai diverse opzioni.

Il più semplice è quello di utilizzare sprintf formattazione che è reso ancora più facile con il metodo String#%:

string = '%s' 

proc = Proc.new { |var| string % var } 

proc.call(123) 
# => "123" 

Questo è un metodo davvero affidabile come tutto ciò che supporta il metodo .to_s funzionerà e non causerà la universo da implodere se contiene codice eseguibile.

+9

'String #%' supporta anche i parametri denominati con Hash come argomento, il che lo avvicina molto alla potenza dell'interpolazione nativa delle stringhe. –

+0

Generalmente uso lo stile C per motivi di compattezza in questo modo, ma come si fa notare fa molto di più. – tadman

+0

Questo fa bene il trucco :) Thx! –

4

Funziona con eval:

proc = Proc.new { |var| eval(%Q{"#{string}"}) } 

(Se vi fidate il valore di stringa.)

+1

Quando citate le virgolette, dovreste probabilmente esprimerlo usando i singoli o '% q []' come: '% q [" # {stringa} "]' per evitare tutte le fughe terribili. – tadman

+0

Hmm ... sembra che "eval" funzioni. Ma forse c'è un altro modo? –

+0

@tadman non interporrà # {string} quindi – arnaud576875

0

È necessario definire la stringa che supporta l'interpolazione al di fuori del proprio Proc?

proc = Proc.new { |var| "#{var}" } 
proc.call(123) # "123" 

Questo sarebbe il modo più pulito che penso.

+0

Vedo che questo non funziona per il tuo particolare esempio ... ma potrebbe ancora essere applicato ad altre situazioni simili. Pubblicherò una risposta migliore separatamente. –

1

È possibile ottenere l'ASCIUTTO che si sta cercando creando una funzione "al curry" (ovvero: un Proc che restituisce un Proc) in cui la funzione interna contiene la stringa di base con le variabili per ogni parte che differisce.

Correggimi se ho torto, ma nel tuo codice dietro il tuo link commentato, l'unica differenza tra le due stringhe è un singolo carattere alla fine. (Anche se non lo è, puoi ancora usare questa tecnica per raggiungere lo stesso obiettivo.) Puoi creare un Proc che restituisca un Proc contenente la tua stringa, quindi chiamare il Proc esterno due volte per i tuoi due caratteri finali:

rails_root = "whatever" # Not variant for the string 
rails_env_prompt = "whatever" #not variant for the string 

spec = Proc.new { |tail_char| 
    Proc.new {|obj, nest_level, *| 
    "#{rails_root} #{rails_env_prompt} #{obj}:#{nest_level}#{tail_char} " 
    } 
} 

Pry.config.prompt = [ spec.call(">"), spec.call("*") ] 

Pry.config.prompt[0].call("My obj", "My Nest Level") 
# result: "whatever whatever My obj:My Nest Level> " 
+0

È complicato :) L'interpolazione delle stringhe dalle risposte accettate funziona per me. –

19

Nel mio caso avevo bisogno di avere la configurazione memorizzata all'interno di un yml, con interpolazione, ma che è interpolata solo quando ne ho bisogno. La risposta accettata con lo Proc mi è sembrata eccessivamente complicata.

In ruby ​​1.8.7 è possibile utilizzare la sintassi % come segue:

"This is a %s verb, %s" % ["nice", "woaaaah"] 

Quando si utilizza almeno 1.9.x ruby ​​(o ruby ​​1.8.7 con i18n) c'è un'alternativa più pulita:

my_template = "This is a %{adjective} verb, %{super}!" 

my_template % { adjective: "nice", super: "woah" } 
=> "This is a nice verb, woah!" 
Problemi correlati