[newbie] make local var visible

Hi All,

I may not be feeling well today, so pardon me pls.

I am modifying/cleaning many scripts here (most of them just a page long,
two at most, and most of them coming fr perl/bash origin).

I encountered a wall though.

Consider,

cat test.rb

#sample script---------------->8
foo=["a","b","c"]

def mfoo
    foo.each do |f|
        p f
    end
end

# go-go-go!
mfoo
#end sample script------------>8

i just enclosed the some commands with def mfoo / end to make a new method
mfoo and make my script cleaner, and besides, i may be calling mfoo again.

running the above, i get:

test.rb

test.rb:4:in `mfoo': undefined local variable or method `foo'

        from test.rb:9

So how can i force foo visible to mfoo()?

Thanks in advance.
-botp

If you really want this, you could prepend an @ to the foo

$ cat mfoo.rb
@foo = [1,2,3]
foo = [5,6,7]

def afoo
  @foo
end

def mfoo
  foo
end

p afoo
p mfoo
$ ruby mfoo.rb
[1, 2, 3]
mfoo.rb:9:in `mfoo': undefined local variable or method `foo' for
#<Object:0xb7ef79c0 @foo=[1, 2, 3]> (NameError)
        from mfoo.rb:13

regards,

Brian

···

On 29/07/05, "Peña, Botp" <botp@delmonte-phil.com> wrote:

Hi All,

I may not be feeling well today, so pardon me pls.

I am modifying/cleaning many scripts here (most of them just a page long,
two at most, and most of them coming fr perl/bash origin).

I encountered a wall though.

Consider,

>cat test.rb

#sample script---------------->8
foo=["a","b","c"]

def mfoo
    foo.each do |f|
        p f
    end
end

# go-go-go!
mfoo
#end sample script------------>8

i just enclosed the some commands with def mfoo / end to make a new method
mfoo and make my script cleaner, and besides, i may be calling mfoo again.

running the above, i get:

>test.rb

>test.rb:4:in `mfoo': undefined local variable or method `foo'
        from test.rb:9

So how can i force foo visible to mfoo()?

Thanks in advance.
-botp

--
http://ruby.brian-schroeder.de/

Stringed instrument chords: http://chordlist.brian-schroeder.de/

I usually use globals... *duck*

but, the following also works since, it think?, all ruby code is
inside class Object ... end

@foo = [1, 2, 3]
class Object
  attr_accessor :foo
end

def mfoo
  puts foo.inspect
end

mfoo

hope this helps

···

On 7/29/05, "Peña, Botp" <botp@delmonte-phil.com> wrote:

Hi All,

I may not be feeling well today, so pardon me pls.

I am modifying/cleaning many scripts here (most of them just a page long,
two at most, and most of them coming fr perl/bash origin).

I encountered a wall though.

Consider,

>cat test.rb

#sample script---------------->8
foo=["a","b","c"]

def mfoo
   foo.each do |f|
       p f
   end
end

# go-go-go!
mfoo
#end sample script------------>8

i just enclosed the some commands with def mfoo / end to make a new method
mfoo and make my script cleaner, and besides, i may be calling mfoo again.

running the above, i get:

>test.rb

>test.rb:4:in `mfoo': undefined local variable or method `foo'
       from test.rb:9

So how can i force foo visible to mfoo()?

Thanks in advance.
-botp

--
Cristi BALAN

def mfoo ... end creates a new scope (or how would you say that in
proper naming), and thus forgets about local variables defined
elsewhere, you can't access foo from within the method.

I think you have 2 options here (maybe more, but these are the ones I
can come up with as a newbie myself):
1) pass foo as an argument.
  def mfoo(foo) ... end
  mfoo(foo)
2) make foo an instance-variable
  @foo = [..]
  def mfoo
     @foo.each...
  end

grtz,
wannes

···

On 29/07/05, "Peña, Botp" <botp@delmonte-phil.com> wrote:

#sample script---------------->8
foo=["a","b","c"]

def mfoo
    foo.each do |f|
        p f
    end
end

# go-go-go!
mfoo
#end sample script------------>8
>test.rb:4:in `mfoo': undefined local variable or method `foo'
        from test.rb:9
So how can i force foo visible to mfoo()?

You could do:

  Foo=["a","b","c"]

  def mfoo
      Foo.each do |f|
          p f
      end
  end

  # go-go-go!
  mfoo

Yet I tend to agree. Even in classes, it just seems so much more
elegant:

  class Bar

    foo = ["a","b","c"] # attribute

    def mfoo
       foo.each do |f|
          p f
       end
    end

  end

But the only way to do that woud be:

1) Irregular attr syntax.

    attr foo = ["a","b","c"]

2) Alternate assignment operator.

    foo := ["a","b","c"]

3) Prefixed local vars.

  %local_var = 'what have you'

I myself have suggested before that

  foo = 10

be essentially equivalent to

  def foo ; 10 ; end

And that constants and methods share the same namespace.

T.

IMO, if you really want clean in the code readability sense, stop trying to transliterate code between languages, and go the usual way:

foo = [ 'something', 'or', 'other']

def mfoo(arg)
  # do stuff with a copy of arg.
  return arg
end

foo = mfoo(foo)

If you really want foo clobbered, I'd possibly either add an Array#mfoo! method, or add it as a singleton to foo. Yes, I'm -that- evil :wink: And resentful of clobbering objects...

David

wannes <oeaniz@gmail.com> writes:

def mfoo ... end creates a new scope (or how would you say
that in proper naming),

You'd say it doesn't create closures.

and thus forgets about local variables defined elsewhere,
you can't access foo from within the method.

I think you have 2 options here (maybe more, but these are
the ones I can come up with as a newbie myself):

1) pass foo as an argument.
  def mfoo(foo) ... end
  mfoo(foo)

2) make foo an instance-variable
  @foo = [..]
  def mfoo
     @foo.each...
  end

You can also define the method as a closure:

   class Module
     public :define_method
   end

   moomin = 123 # local variable
   def foo ; moomin end # no closure
   (class << self ; self end).
     define_method(:bar) { moomin } # closure

   foo # NameError: undefined local variable or method `moomin'
   bar #=> 123

But this is not a very practical or useful thing to do.
Usually, you would be working in some class of your own,
in which case you would simply use an instance variable.

···

--
Daniel Brockman <daniel@brockman.se>

    So really, we all have to ask ourselves:
    Am I waiting for RMS to do this? --TTN.