Für eine einfache Lösung, verwenden Sie OpenStruct :
require 'erb'
require 'ostruct'
namespace = OpenStruct.new(name: 'Joan', last: 'Maragall')
template = 'Name: <%= name %> <%= last %>'
result = ERB.new(template).result(namespace.instance_eval { binding })
#=> Name: Joan Maragall
Der obige Code ist einfach genug, hat aber (mindestens) zwei Probleme: 1) Da er sich auf OpenStruct
ein Zugriff auf eine nicht existierende Variable ergibt nil
während Sie es wahrscheinlich vorziehen würden, wenn es geräuschvoll scheitern würde. 2) binding
wird innerhalb eines Blocks aufgerufen, d.h. in einer Schließung, so dass alle lokalen Variablen in den Geltungsbereich einbezogen werden (diese Variablen schatten die Attribute der Struktur!).
Hier ist also eine andere Lösung, die zwar ausführlicher ist, aber keines dieser Probleme aufwirft:
class Namespace
def initialize(hash)
hash.each do |key, value|
singleton_class.send(:define_method, key) { value }
end
end
def get_binding
binding
end
end
template = 'Name: <%= name %> <%= last %>'
ns = Namespace.new(name: 'Joan', last: 'Maragall')
ERB.new(template).result(ns.get_binding)
#=> Name: Joan Maragall
Wenn Sie dies häufig verwenden, sollten Sie natürlich eine String#erb
Erweiterung, mit der Sie etwas schreiben können wie "x=<%= x %>, y=<%= y %>".erb(x: 1, y: 2)
.