On Mon, Mar 12, 2007 at 06:00:21PM +0900, Mike wrote:
I know it but imagine you must do it 100 times?
I’d rather write:
set_default(var1, 15)
set_default(myvar1, “string”)
…
set_default(lastvar, myhash)
OK, if you really insist:
---- 8< -------------------------------------------------
require ‘rubygems’
require ‘active_support/binding_of_caller’
def set_default(var, val)
Binding.of_caller do |binding|
eval("#{var} ||= #{val}", binding)
end
end
var1 = nil # <<<<<<< A
set_default(“var1”, 5)
set_default(“var1”, 15)
puts var1 # <<<<<<< B (prints 5)
---- 8< -------------------------------------------------
This works as written; but you’ll find you get bitten by the static
nature
of local variables if you remove line “A”. It then fails.
This is because of the ambiguity in line B: “puts var1” could be
referring
to a method call - puts self.var1() - or a local variable. This
ambiguity is
resolved at parse time, before any code has been executed at all,
simply
based on whether a statement of the form “var1 = xxx” has been seen
earlier
in the file.
If you remove line A, then line B is already resolved as puts
self.var1()
before any code has been executed.
Now, macros would be fine here - but only if these macros were expanded
at
parse time. That makes them very static, and not very useful in a
dynamic
language like Ruby.
As others have said before: provide a real example of where you would
need
macros, not a noddy “var ||= val” replacement, and we’ll show you how
Rubyists would handle this case.
Regards,
Brian.