Forum: Ruby Questionable behavior

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
unknown (Guest)
on 2006-05-26 17:55
(Received via mailing list)
I'm getting some very strange behavior from a conditional statement --
I can;t imagine how it is happeneing and I wondering if I stumbled upon
some sort of bug in Ruby. Although I have no idea how it could even
occuer, perhaps someone else can see it. Here's the code:

  p pkg
  p pkg.gem
  p pkg.gem
  if pkg.gem
      p "HERE"
      pkg = pkg.__merge__( pkg.gem )
  end
  p pkg

This prints

  #<OpenObject....>
  nil
  nil
  nil

Notice it does not print "HERE" yet by that last print pkg has somehow
become nil! Note that I repeated 'p pkg.gem' to show that it has
nothing to do with calling this statment. Now if I remark out the pkg
assignment:

  p pkg
  p pkg.gem
  p pkg.gem
  if pkg.gem
      p "HERE"
      #pkg = pkg.__merge__( pkg.gem )
  end
  p pkg

I get

  #<OpenObject....>
  nil
  nil
  #<OpenObject....>

As it should be. How is this possible?

FYI
Ubuntu Linux
ruby 1.8.4 (2005-12-24) [i486-linux]

Thanks,
T.
Mat S. (Guest)
on 2006-05-26 18:58
(Received via mailing list)
On May 26, 2006, at 9:54 AM, removed_email_address@domain.invalid wrote:

>       p "HERE"
>
>       #pkg = pkg.__merge__( pkg.gem )
> As it should be. How is this possible?
I'd be happy to test it here and see if I can replicate it.  But I
don't know what an OpenObject is.
-Mat
Dominik B. (Guest)
on 2006-05-26 19:05
(Received via mailing list)
Hi,

On Fri, 26 May 2006 15:54:21 +0200, <removed_email_address@domain.invalid> 
wrote:

> I'm getting some very strange behavior from a conditional statement --
> I can;t imagine how it is happeneing and I wondering if I stumbled upon
> some sort of bug in Ruby. Although I have no idea how it could even
> occuer, perhaps someone else can see it. Here's the code:

No, that is no bug, it' a feature ;-)

here pkg is a method call
>   p pkg
>   p pkg.gem
>   p pkg.gem
>   if pkg.gem
>       p "HERE"
after this line pkg is a local variable (because you assign to it)
>       pkg = pkg.__merge__( pkg.gem )
>   end
unintialized local variables default to nil, so it prints nil
>   p pkg
>
> This prints
>
>   #<OpenObject....>
>   nil
>   nil
>   nil

If you want the method call you can use pkg().

Here is another example:

$ cat lvar_tst.rb
def a
         "method"
end

def test
         p a
         p a()
         if false
                 a = 23
         end
         p a
         p a()
end

test
$ ruby lvar_tst.rb
"method"
"method"
nil
"method"


This is just the way Ruby (it's parser) handles local variables, but I
think matz said that this will be made more "consistent" in future
versions (i.e. if something is a lvar at some point in a scope it will
be
an lvar everywhere in this scope and you might get a warning for your
above code, like "use of lvar before initialization")

Hope that helps,
Dominik
unknown (Guest)
on 2006-05-26 19:34
(Received via mailing list)
It would be tricky to run the test in that the code is pretty deep
inside my application. If your willing though I would be happy to send
you the whole package to try. FYI, it's the Reap project.

OpenObject is similar to OpenStruct and can be found in Ruby F.s.

Thanks,
T.
unknown (Guest)
on 2006-05-26 19:49
(Received via mailing list)
Dominik B. wrote:

> > I'm getting some very strange behavior from a conditional statement --
> > I can;t imagine how it is happeneing and I wondering if I stumbled upon
> > some sort of bug in Ruby. Although I have no idea how it could even
> > occuer, perhaps someone else can see it. Here's the code:
>
> No, that is no bug, it' a feature ;-)

Oh, I love those kind of "features".... NOT!

> This is just the way Ruby (it's parser) handles local variables, but I
> think matz said that this will be made more "consistent" in future
> versions (i.e. if something is a lvar at some point in a scope it will be
> an lvar everywhere in this scope and you might get a warning for your
> above code, like "use of lvar before initialization")

Why does it do this and why is that a good solution? How unintuitive
can it possibly be? Why doesn't it just convert the refernce to a lvar
when it evaluates?  Why does the parser have to look ahead and
pre-judge the reference. You got code evaluating in a false condition
--so anti-dynamic!

Sigh. Okay so referncing it as a local var --EVEN IN UNEVALUATED CODE
changes a refernce to a local variable. Great! I was trying to take
advantage of the isomorphism of local vars and metods --which I thought
WAS a feature. So much for that.

Thanks Dominik,
T.
unknown (Guest)
on 2006-05-26 19:56
(Received via mailing list)
Ah, despite my rant, there is an easy solution. And it makes it very
clear the oddness of the way Ruby parser work here:

      if pkg.gem
        pkg = pkg.__merge__( pkg.gem )
      else
        pkg = pkg
      end

It won't work without the 'pkg = pkg'.

T.
Mat S. (Guest)
on 2006-05-26 20:59
(Received via mailing list)
Sounds like it's pretty wrapped up.  Interesting fix.  And something
to keep in mind for later.  Hopefully later version of ruby will
print warnings on this sort of thing.
-Mat
This topic is locked and can not be replied to.