Robert Klemme
2/12/2008 4:11:00 PM
2008/2/12, Brett Williams <brettandbecky@gmail.com>:
> I am trying to make a "source" command for Ruby (a la sh or tcl), but I
> think lexical scoping is tripping me up. I've done a lot of reading
> about bindings, and it seems I just can't do what I'm trying to do.
>
> def source(filename, bind = TOPLEVEL_BINDING)
> code = nil
> File.open(filename) { |f| code = f.read }
> eval(code, bind)
> end
>
> This works as I would like, with the exception of local variables
> present in the sourced file. For example, if I had something like this
> in the sourced file:
>
> x = "value set in sourced file"
>
> then I get an error : undefined local variable or method 'x'
Can you show more code? For me it works:
17:05:12 ~
$ echo "x=123; puts x" | ruby -e 'eval(ARGF.read, TOPLEVEL_BINDING)'
123
17:05:18 ~
$ echo "x=123; puts x" | ruby -e 'eval(ARGF.read, binding)'
123
17:05:25 ~
$
Or are you seeing this:
17:05:25 ~
$ echo "x=123" | ruby -e 'eval(ARGF.read, binding); puts x'
-e:1: undefined local variable or method `x' for main:Object (NameError)
17:06:31 ~
$
> unless I extend the scope of x by setting it before sourcing the file.
Like
17:06:31 ~
$ echo "x=123" | ruby -e 'x=1; eval(ARGF.read, binding); puts x'
123
17:07:32 ~
$
This is because local variables are detected at compile time. That's
why Ruby thinks "x" in my bit above is a method because there is no
assignment.
> Is there any way to accomplish what I want? I could work around this by
> sticking to instance variables or *gulp* global variables for this
> application, but before I throw in the towel I wanted to throw this out
> to people here.
A global is probably much more appropriate here. If the code you
source somehow generates configuration settings then maybe you can set
a global Hash that will receive values. It depends on the larger
context of what you want to achieve.
> P.S.: Things have changed since I was a pretty regular poster back in
> 2002-2003... ;)
Does this have to do with your email address? ;-) If yes, congrats
and greetings to Becky!
Cheers
robert
--
use.inject do |as, often| as.you_can - without end