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
Andrew Chen wrote:
instance_eval(File.read('param.txt'))
How about:
load 'param.txt'
Best regards,
Jari Williamsson
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
···
On Thu, Feb 21, 2008 at 1:44 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?
>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)
···
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,
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
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
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
···
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?
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
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
···
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?
You want to do variable assignment via a file, right? Is it not
possible to do this?
$ cat a.yml
name: John
$ cat a.rb
h = YAML.load_file('a.yml')
puts h['name']
Todd
···
On Thu, Feb 21, 2008 at 3:14 PM, Andrew Chen <hangfei@gmail.com> wrote:
Also, the load_yaml won't work, because I need to setup variables
dynamically.
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
Hi all,
The reason is it's a local variable inside a block. Have a look at this, for
example:
1.upto(5) {|i| j = i ** 2; puts j}
1
4
9
16
25
=> 1
j
NameError: undefined local variable or method `j' for main:Object
from (irb):2
j is undefined after the block's execution. If we let j be defined before
the block, however, ...
j = "anything at all, really"
=> "anything at all, really"
1.upto(5) {|i| j = i ** 2; puts j}
1
4
9
16
25
=> 1
j
=> 25
Since j is already defined, Ruby uses that instead. Confusing, but could be
useful.
Arlen