Scope questions

Hi guys, I am a recent Ruby convert (from PERL), and I am wondering if
there
is a way to get some of the behavior that I am
comfortable with with regards to scope.

In PERL the following code:

my $var=1;
{
my $var=2;
print “inner=$var\n”
}
print “outer=$var\n”

yields:

inner=2
outer=1

However in Ruby, I’m not sure how to get the same behavior. I tried:

var=1
begin
var=2
print “inner=#{var}\n”
end
print “outer=#{var}\n”

which yields a different output than the PERL code. Is this type of
thing
possible in Ruby without creating a class?

Thanks!

On Tue, Sep 18, 2007 at 11:29:25PM +0900, Mister R. wrote:

my $var=1;
{
my $var=2;
print “inner=$var\n”
}
print “outer=$var\n”

If the variables really are different, then use a different variable
name. Even though you can do this in perl, that does not make it a good
idea.

Methods should, in general, be short enough that you do not have naming
conflicts between local variables. If you find yourself running into
this a lot, you are probably doing too much in one method, which can
make code harder to read and to refactor later on.

Matz has discussed some syntaxes for what you want for Ruby 2.0, such
as:

var = 1
local { |var|
var = 2
}
puts var #=> 1

(so that block parameters are always local to the block) but I don’t
know what the current status of this is.

Paul

On 9/18/07, Mister R. [email protected] wrote:

which yields a different output than the PERL code. Is this type of thing
possible in Ruby without creating a class?

is def method good enough for you?

irb(main):001:0> def m
irb(main):002:1> var = 2
irb(main):003:1> puts “inner var = #{var}”
irb(main):004:1> end
=> nil
irb(main):005:0> var = 1
=> 1
irb(main):006:0> m
inner var = 2
=> nil
irb(main):007:0> puts “outer var = #{var}”
outer var = 1
=> nil

you can nest methods too

irb(main):008:0> def m2
irb(main):009:1> var = 1
irb(main):010:1> def m3
irb(main):011:2> var = 2
irb(main):012:2> puts “inner var = #{var}”
irb(main):013:2> end
irb(main):014:1> puts “outer var = #{var}”
irb(main):015:1> end
=> nil
irb(main):016:0> m2
outer var = 1
=> nil
irb(main):017:0> m2.m3
outer var = 1
inner var = 2
=> nil
irb(main):018:0> m3
inner var = 2
=> nil

kind regards -botp

On Wed, Sep 19, 2007 at 12:59:58AM +0900, botp wrote:

outer var = 1
=> nil
irb(main):017:0> m2.m3
outer var = 1
inner var = 2
=> nil
irb(main):018:0> m3
inner var = 2
=> nil

This might not be doing what you think it is:

irb(main):020:0> $VERBOSE = true
=> true
irb(main):023:0> m2.m3
(irb):9: warning: method redefined; discarding old m3
outer var = 1
inner var = 2
=> nil
irb(main):024:0> m2
(irb):9: warning: method redefined; discarding old m3
outer var = 1
=> nil
irb(main):025:0> nil.m3
inner var = 2
=> nil

(your example made it look like m3 is inside m2, which it isn’t. m2 is
returning nil, and since you made m3 a public method, m2.m3 is the same
as
m2(); nil.m3())

Paul

From: Paul B. [mailto:[email protected]]

On Wed, Sep 19, 2007 at 12:59:58AM +0900, botp wrote:

> irb(main):008:0> def m2

> irb(main):009:1> var = 1

> irb(main):010:1> def m3

> irb(main):011:2> var = 2

> irb(main):012:2> puts “inner var = #{var}”

> irb(main):013:2> end

> irb(main):014:1> puts “outer var = #{var}”

> irb(main):015:1> end

> => nil

> irb(main):016:0> m2

> outer var = 1

> => nil

> irb(main):017:0> m2.m3

> outer var = 1

> inner var = 2

> => nil

> irb(main):018:0> m3

> inner var = 2

> => nil

This might not be doing what you think it is:

irb(main):020:0> $VERBOSE = true

=> true

irb(main):023:0> m2.m3

(irb):9: warning: method redefined; discarding old m3

outer var = 1

inner var = 2

=> nil

irb(main):024:0> m2

(irb):9: warning: method redefined; discarding old m3

outer var = 1

=> nil

irb(main):025:0> nil.m3

inner var = 2

=> nil

my bad. sorry for the confusion.

i simply meant that you can define m3 inside m2, and that its var will
not clash with that of m2, and that you can only invoke m3 if you’ve
invoked m2 already.

in other words, you cannot do m3 right away. you’ll have to do m2 first,
or if you wish to run m3 immediately, you may follow it thru after m2,
or m2.m3. i guess it would be clearer if i nest it further like
m1.m2.m3.m4. i could go that route to reach m4 immediately, or just wait
and just do m1; then later, m2, then later m3… from then on m4 will
be defined and i could then just invoke it plainly as m4. (of course by
this behaviour, one can also redefine methods by inserting them within
methods)

pls correct me if i’m wrong, i usually make stupid assumptions based on
my limited experience. pardon a nuby pls :frowning:

kind regards -botp