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 C.
Andrew C. wrote:
instance_eval(File.read(‘param.txt’))
How about:
load ‘param.txt’
Best regards,
Jari W.
On Thu, Feb 21, 2008 at 1:44 PM, Andrew C. [email protected] wrote:
#!/usr/bin/env ruby
require ‘erb’
name = nil
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
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 B.
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
On Thu, Feb 21, 2008 at 2:10 PM, Andrew C. [email protected] 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
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 C.
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 C.
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 W.
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 C.
On Thu, Feb 21, 2008 at 2:44 PM, Andrew C. [email protected] 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
On Thu, Feb 21, 2008 at 3:14 PM, Andrew C. [email protected] wrote:
Also, the load_yaml won’t work, because I need to setup variables
dynamically.
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
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