[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Where does instance_eval _magically_ set the variable to?

Andrew Chen

2/21/2008 7:42:00 PM

Hi,

I use the instance_eval to merge template file and parameter files.

>cat param.txt
name="John"
>cat tmpl.txt
my name is: <%= name %>

>cat template.rb
#!/usr/bin/env ruby
require 'erb'

instance_eval(File.read('param.txt'))
puts ERB.new(File.read("tmpl.txt")).result(binding)

puts name

>template.rb
my name is: John
template.rb:7: undefined method `name' for main:Object (NoMethodError)


Where is the variable "name" set to? How to access it?
It must be somewhere, since it is used in the tmpl.txt file.

Is there any "magic" namespace in Ruby?

Thanks
~Andrew Chen
12 Answers

Jari Williamsson

2/21/2008 8:01:00 PM

0

Andrew Chen wrote:

> instance_eval(File.read('param.txt'))

How about:
load 'param.txt'


Best regards,

Jari Williamsson

Todd Benson

2/21/2008 8:04:00 PM

0

On Thu, Feb 21, 2008 at 1:44 PM, Andrew Chen <hangfei@gmail.com> wrote:
> Hi,
>
> I use the instance_eval to merge template file and parameter files.
>
> >cat param.txt
> name="John"
> >cat tmpl.txt
> my name is: <%= name %>
>
> >cat template.rb
> #!/usr/bin/env ruby
> require 'erb'
>

name = nil

> instance_eval(File.read('param.txt'))
> puts ERB.new(File.read("tmpl.txt")).result(binding)
>
> puts name
>
> >template.rb
> my name is: John
> template.rb:7: undefined method `name' for main:Object (NoMethodError)
>
>
> Where is the variable "name" set to? How to access it?
> It must be somewhere, since it is used in the tmpl.txt file.
>
> Is there any "magic" namespace in Ruby?

It's just a scope issue. If you use name = nil like I did above you
should be okay. I wonder, though, why you would want to
#instance_eval instead of using #load.

Also, some rubyists advocate using the block method of File.open as
well. I'm not sure if File.read closes the file automatically.

hth,
Todd

Andrew Chen

2/21/2008 8:07:00 PM

0

Jeri,

> How about:
> load 'param.txt'
>

Load doesn't get the variable into the current namespace. Maybe I
used it wrong?

>cat param.txt
name='John'
>cat load.rb
#!/usr/bin/env ruby

load 'param.txt'

puts name
>./load.rb
../load.rb:5: undefined local variable or method `name' for main:Object
(NameError)
>

Todd Benson

2/21/2008 8:22:00 PM

0

On Thu, Feb 21, 2008 at 2:04 PM, Todd Benson

> I wonder, though, why you would want to
> #instance_eval instead of using #load.

If those are just parameters, you might consider using the YAML
library. Just a thought...

Todd

Todd Benson

2/21/2008 8:28:00 PM

0

On Thu, Feb 21, 2008 at 2:10 PM, Andrew Chen <hangfei@gmail.com> wrote:
> Jeri,
>
>
> > How about:
> > load 'param.txt'
> >
>
> Load doesn't get the variable into the current namespace. Maybe I
> used it wrong?

Nope, you didn't. I'm sure there's a reason for that; probably to
prevent accidental corruption of namespace. If you must use load,
you'll have to build methods in the loaded file instead of
variables...

def name; 'John'; end

...which may or may not work for you.

I suggest going the YAML route. I suppose there are other ways to
serialize data, too.

Todd

Andrew Chen

2/21/2008 8:42:00 PM

0

Todd,
Yes, load more proper here than instance_eval.
Also, I will use File.open block instead of File.read.

However, this is still a mystery:
In the original code, where did the variable "name" go? How to access
that?

When I use load 'param.txt', how to access variables loaded from the
param.txt file?

>cat param.txt
Name='John'
Name='John'
last="smith"
>./load.rb
../param.txt:2: warning: already initialized constant Name
John
../load.rb:6: undefined local variable or method `last' for main:Object
(NameError)
>

Thanks
~Andrew Chen

Andrew Chen

2/21/2008 8:47:00 PM

0

Todd,
"I suggest going the YAML route. I suppose there are other ways to
serialize data, too."

I thought about yaml.

However, I want to make a parameter file for easy template. Maybe I
can do a pre-transformation from ruby data to yaml, then from yaml to
data.

My goal is to read data from a parameter file (ruby data format) into
memory, without @, $, Uppercase_name.

Thanks
~Andrew Chen

Andrew Chen

2/21/2008 9:11:00 PM

0

Todd,
There are some subtle difference between load and instance_eval.
In this case, instance_eval works, the load doesn't.

I still have no idea where the instance_eval put the variables at.

>cat param.txt
name="John"
>cat tmpl.txt
my name is: <%= name %>
>cat erb_instance_eval.rb
#!/usr/bin/env ruby

require 'erb'

instance_eval(File.read("param.txt"))
#load "param.txt"
puts ERB.new(File.read("tmpl.txt")).result(binding)
>./erb_instance_eval.rb
my name is: John


>cat erb_load.rb
#!/usr/bin/env ruby

require 'erb'

#instance_eval(File.read("param.txt"))
load "param.txt"
puts ERB.new(File.read("tmpl.txt")).result(binding)
>./erb_load.rb
(erb):1: undefined local variable or method `name' for main:Object
(NameError)
from ./erb_load.rb:7
>

Also, the load_yaml won't work, because I need to setup variables
dynamically.

Thanks
~Andrew Chen

Jari Williamsson

2/21/2008 9:49:00 PM

0

Strange. The REALLY interesting stuff starts to happen when you
encapsulate the code in a module. (name becomes the name of the module)


Best regards,

Jari Williamsson


Andrew Chen wrote:
> Todd,
> There are some subtle difference between load and instance_eval.
> In this case, instance_eval works, the load doesn't.
>
> I still have no idea where the instance_eval put the variables at.
>
> >cat param.txt
> name="John"
> >cat tmpl.txt
> my name is: <%= name %>
> >cat erb_instance_eval.rb
> #!/usr/bin/env ruby
>
> require 'erb'
>
> instance_eval(File.read("param.txt"))
> #load "param.txt"
> puts ERB.new(File.read("tmpl.txt")).result(binding)
> >./erb_instance_eval.rb
> my name is: John
>
>
> >cat erb_load.rb
> #!/usr/bin/env ruby
>
> require 'erb'
>
> #instance_eval(File.read("param.txt"))
> load "param.txt"
> puts ERB.new(File.read("tmpl.txt")).result(binding)
> >./erb_load.rb
> (erb):1: undefined local variable or method `name' for main:Object
> (NameError)
> from ./erb_load.rb:7
> >
>
> Also, the load_yaml won't work, because I need to setup variables
> dynamically.
>
> Thanks
> ~Andrew Chen
>
>

Todd Benson

2/21/2008 9:53:00 PM

0

On Thu, Feb 21, 2008 at 2:44 PM, Andrew Chen <hangfei@gmail.com> wrote:
> Todd,
> Yes, load more proper here than instance_eval.
> Also, I will use File.open block instead of File.read.
>
> However, this is still a mystery:
> In the original code, where did the variable "name" go? How to access
> that?

It's signed up for garbage collection when you exit the #instance_eval
or #load method (I think). In other words, it has a temporary
existence. There's nothing holding on to it (referencing it).

Todd