Adding variables to a binding


#1

I need to run an ERB template (a normal Rails view template) in a Rails
model (and then write the result to a file). The problem is that I need
to run it in the scope of the calling controller. So I was thinking of
creating a binding in the controller and pass into the model and use the
binding there. I do however need to add variables from the model scope
into the binding. How do I do this? Thought of using eval with the
binding but it only seems to take an input string to eval (a block would
have been nice I think).

The reason I do this is that the model in question is a STI model and
each sub class may need to add different variables. If you can think of
a better way to accomplish what I want I’ll be glad to hear :slight_smile:

Thanks,

/Marcus


#2

On 2/11/06, marcus removed_email_address@domain.invalid wrote:

each sub class may need to add different variables. If you can think of
a better way to accomplish what I want I’ll be glad to hear :slight_smile:

If I understand correctly, you want something like this:

def outerscope
innerscope(binding)
p foo,bar,baz #problematic
end

def innerscope(bdg)
eval “foo=bar=baz=1”, binding
end

This works, sort of. Unfortunately, ruby’s local variables are
lexically scoped, which means that once you get back to outerscope,
foo, bar, and baz (which are now in outerscope’s binding) won’t be
recognized as local variables. (Unless you use eval again to get at
them…) For most purposes, they are unusable.

How about this instead:

def outerscope
vars={}
innerscope(vars)
p vars[:foo],vars[:bar],vars[:baz]
end

def innerscope(vars)
vars[:foo]=vars[:bar]=vars[:baz]=1
end


#3

Caleb C. skrev:

def innerscope(vars)
vars[:foo]=vars[:bar]=vars[:baz]=1
end

The problem is that ERB#result(binding) takes a binding so I need the
binding. The templates used in this case relies on Rails rules (member
variables in a controller are available in the ERB template) and I need
to create a binding containing everything from the controller scope (and
then add the new needed stuff from the model).

What about passing a block from outer scope and call it from inner scope
and pass in a Hash with variables from the inner scope, then loop over
the variables and add those as instance members (using instance_eval),
create the binding (inside the block) and then invoke ERB.result. Could
that work?

/Marcus


#4

DÅ?a Sobota 11 Február 2006 23:12 marcus napísal:

each sub class may need to add different variables. If you can think of
a better way to accomplish what I want I’ll be glad to hear :slight_smile:

Thanks,

/Marcus

I -think- instance variables get exported from the ERB template into the
calling method.

David V.