On Sat, Mar 14, 2009 at 4:47 PM, Michael W. Ryder
[email protected] wrote:
=> nil
it works as I want. Â But when I try:
I can see that if I create the variable before running the method the
variable is set even after the method ends. Â Which of course brings up the
question of why is the change visible outside of the block?
Ruby blocks are closures, and they therefore capture the environment
where they are created. So if a local variable exists in that
environment when the block is created, the block has access to it, and
changes will affect the externally-created local variable. But new
local variables introduced in the block are local to the block. In
essence, the environment of the block is subordinate to the
environment in which it is created.
Why do you need variables called “name” (etc.) anyway? Why not use a
hash, so that h[“name”] contains the name (“John D.”), h[“street”]
contains the street, and so on? So:
I have been programming in Business Basic for over 20 years and am used to
reading a file with a statement like:
 Read(1,Key=“1234”)Name$,Street$,City$,State$,Zip$,*,Telephone$
and then using those variables.
Assuming you have a “keyed_read” method defined properly, you can easily
do:
name, street, city, state, zip, _, telephone =
data_file.keyed_read(:key=>“1234”)
But the thing that is harder is dynamically assigning variable names
based on a array provided. Using hashes or structs are the more
idiomatic Ruby ways of doing something similar to that. Its possible
to do something very close to what you were attempting with instance
variables using Object#instance_variable_set.
irb(main):036:0> v.zip(e).each { |var, val|
irb(main):037:1* begin
irb(main):038:2* self.instance_variable_set((“@”+var).to_sym,val)
irb(main):039:2> rescue
irb(main):040:2> end
irb(main):041:1> }
=> [[“name”, “John D.”], [“street”, “123 Main St”], [“city”,
“Anywhere”], [“state”, “US”], [“zip”, “01234-5678”], [“*”, “ab123”],
[“telephone”, “1234567890”]]
irb(main):042:0> @name
=> “John D.”
So if you want to do it that way, you can. (Note, I’m assuming that
the ‘*’ is a special symbol for a value you don’t want to store, if
not, you’ll have to add some logic to map that to a valid instance
variable name.)