From: Rocky Bernstein Date: 2008-03-14T11:13:11+09:00 Subject: Re: Ruby 1.8.6 binding value after "if" expression evaluation ------=_Part_1007_33241428.1205460801685 Content-Type: multipart/alternative; boundary="----=_Part_1008_23213919.1205460801686" ------=_Part_1008_23213919.1205460801686 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline I think I've found why this is happening. The trace hook for NODE_IF is getting called a before the expression evaluation occurs when it should be called afterwards. Attached is a patch. I will also update #18722with this information. Thanks. On Thu, Mar 13, 2008 at 2:32 PM, Rocky Bernstein wrote: > Thanks. The output you report matches what I get in 1.8.6 and suggests > where to start looking for a bug. I'm not sure this is strictly related to > blocks. In particular try this: > > x = 6.2*1 if > x=6.1 > > The line break after the "if" is intentional since it more clearly shows > which part gets run when. In this code, > first there are two stops on the x=6.1 presumably before and after the > assignment. But by the time of the c-call to multiply 6.2*1, the value of > x is 6.1. It is like some sort of register flushing that is going before > the c-call, but again that's pure guess. > > On Thu, Mar 13, 2008 at 12:59 PM, Yemi I. D. Bedu > wrote: > > > Hello, > > > > I tried this and it has to do with implicit / explicit block. Also I > > expanded example: > > > > > > > > p RUBY_VERSION > > > > > > > > def trace_func(event, file, line, id, binding, klass, *) > > > > printf("%s:%d (%s) x=%s\n", file, line, event, eval("x", binding)) > > > > end > > > > > > > > set_trace_func method(:trace_func).to_proc > > > > > > > > x=2 > > > > (x=3.2) if x=3.1 > > > > begin x=4.2 end if x=4.1 > > > > x=5.2 if x=5.1 > > > > x=6.2*1 if x=6.1*1 > > > > if x=7.1 then x=7.2 end > > > > x=8 > > > > x=9 > > > > > > > > My Results were: > > > > > > > > "1.8.2" > > > > > > > > tt.rb:9 (line) x= > > > > > > > > tt.rb:10 (line) x=2 > > > > tt.rb:10 (line) x=2 > > > > tt.rb:10 (line) x=3.1 > > > > > > > > tt.rb:11 (line) x=3.2 > > > > tt.rb:11 (line) x=3.2 > > > > tt.rb:11 (line) x=4.1 > > > > > > > > tt.rb:12 (line) x=4.2 > > > > tt.rb:12 (line) x=4.2 > > > > > > > > tt.rb:13 (line) x=5.2 > > > > tt.rb:13 (line) x=5.2 > > > > tt.rb:13 (c-call) x=5.2 > > > > tt.rb:13 (c-return) x=5.2 > > > > tt.rb:13 (c-call) x=6.1 > > > > tt.rb:13 (c-return) x=6.1 > > > > > > > > tt.rb:14 (line) x=6.2 > > > > tt.rb:14 (line) x=6.2 > > > > tt.rb:14 (line) x=7.1 > > > > > > > > tt.rb:15 (line) x=7.2 > > > > > > > > tt.rb:16 (line) x=8 > > > > > > > > You would need to either have parens, explicit block or use the other if > > form to get that last firing from the trace. It seems to token out each > > expression unit on a line and then call eval to get the previous lines > > value. I don't know if you can confirm this on your 1.8.6 install. The > > lines with the multiply do func calls so they eval before going into the new > > env and when the come back. You might want to have a more complex expression > > execute like a list comprehension or a map. Good day. > > > > Yemi Bedu > > > > P&R Fasteners, Inc. > > P&R Castings, LLC. > > 325 Pierce St > > Somerset, NJ 08873 > > (T) 732-302-3600 > > (F) 732-302-3636 > > ------------------------------ > > > > *From:* Rocky Bernstein [mailto:rocky.bernstein@gmail.com] > > *Sent:* Wednesday, March 12, 2008 11:21 PM > > *To:* ruby-core@ruby-lang.org > > *Subject:* Ruby 1.8.6 binding value after "if" expression evaluation > > > > > > > > Here's another trace hook weirdness that I've encountered. > > > > Consider this program and its output: > > > > def trace_func(event, file, line, id, binding, klass, *) > > printf("%s:%d (%s) x=%s\n", file, line, event, eval("x", binding)) > > end > > set_trace_func method(:trace_func).to_proc > > x=5 > > x=6.2 if x=6.1 > > x=7 > > > > > > $ ruby bug2.rb > > bug2.rb:6: warning: found = in conditional, should be == > > bug2.rb:5 (line) x= > > bug2.rb:6 (line) x=5 > > bug2.rb:6 (line) x=5 > > bug2.rb:7 (line) x=6.2 > > > > Why does x appear to have value 5 the second time on line 7 rather than > > 6.1? > > > > Looking at eval.c what's supposed to happen (I think) is that the trace > > hook is called before the expression (x=6.1) is evaluated and then > > called before the assignment "x=6.2" in which case it should have value > > 6.1, not 5. > > > > Can anyone explain why this happens? > > > > Again this is ruby 1.8.6 > > > > ------=_Part_1008_23213919.1205460801686 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline I think I've found why this is happening. The trace hook for NODE_IF is getting called a before the expression evaluation occurs when it should be called afterwards. Attached is a patch. I will also update  #18722 with this information.

Thanks.

On Thu, Mar 13, 2008 at 2:32 PM, Rocky Bernstein <rocky.bernstein@gmail.com> wrote:
Thanks. The output you report matches what I get in 1.8.6 and suggests where to start looking for a bug. I'm not sure this is strictly related to blocks. In particular try this:

x = 6.2*1 if
  x=6.1

The line break after the "if" is intentional since it more clearly shows which part gets run when. In this code,
first there are two stops on the x=6.1 presumably before and after the assignment. But by the time of the c-call to multiply 6.2*1, the value of x is 6.1. It is like some sort of register flushing that is going before the c-call, but again that's pure guess.

On Thu, Mar 13, 2008 at 12:59 PM, Yemi I. D. Bedu <yemi@weldfast.com> wrote:

Hello,

 I tried this and it has to do with implicit / explicit block. Also I expanded example:

 

p RUBY_VERSION

 

def trace_func(event, file, line, id, binding, klass, *)

  printf("%s:%d (%s) x=%s\n", file, line, event, eval("x", binding))

end

 

set_trace_func method(:trace_func).to_proc

 

x=2

(x=3.2) if x=3.1

begin x=4.2 end if x=4.1

x=5.2 if x=5.1

x=6.2*1 if x=6.1*1

if x=7.1 then x=7.2 end

x=8

x=9

 

My Results were:

 

"1.8.2"

 

tt.rb:9 (line) x=

 

tt.rb:10 (line) x=2

tt.rb:10 (line) x=2

tt.rb:10 (line) x=3.1

 

tt.rb:11 (line) x=3.2

tt.rb:11 (line) x=3.2

tt.rb:11 (line) x=4.1

 

tt.rb:12 (line) x=4.2

tt.rb:12 (line) x=4.2

 

tt.rb:13 (line) x=5.2

tt.rb:13 (line) x=5.2

tt.rb:13 (c-call) x=5.2

tt.rb:13 (c-return) x=5.2

tt.rb:13 (c-call) x=6.1

tt.rb:13 (c-return) x=6.1

 

tt.rb:14 (line) x=6.2

tt.rb:14 (line) x=6.2

tt.rb:14 (line) x=7.1

 

tt.rb:15 (line) x=7.2

 

tt.rb:16 (line) x=8

 

You would need to either have parens, explicit block or use the other if form to get that last firing from the trace. It seems to token out each expression unit on a line and then call eval to get the previous lines value. I don't know if you can confirm this on your 1.8.6 install. The lines with the multiply do func calls so they eval before going into the new env and when the come back. You might want to have a more complex expression execute like a list comprehension or a map. Good day.

Yemi Bedu

P&R Fasteners, Inc.
P&R Castings, LLC.
325 Pierce St
Somerset, NJ 08873
(T) 732-302-3600
(F) 732-302-3636


From: Rocky Bernstein [mailto:rocky.bernstein@gmail.com]
Sent: Wednesday, March 12, 2008 11:21 PM
To: ruby-core@ruby-lang.org
Subject: Ruby 1.8.6 binding value after "if" expression evaluation

 

Here's another trace hook weirdness that I've encountered.

Consider this program and its output:

def trace_func(event, file, line, id, binding, klass, *)
  printf("%s:%d (%s) x=%s\n", file, line, event, eval("x", binding))
end
set_trace_func method(:trace_func).to_proc
x=5
x=6.2 if x=6.1
x=7


$ ruby bug2.rb
bug2.rb:6: warning: found = in conditional, should be ==
bug2.rb:5 (line) x=
bug2.rb:6 (line) x=5
bug2.rb:6 (line) x=5
bug2.rb:7 (line) x=6.2

Why does x appear to have value 5 the second time on line 7 rather than 6.1?

Looking at eval.c what's supposed to happen (I think) is that the trace hook is called before the expression (x=6.1) is evaluated and then called before the assignment "x=6.2" in which case it should have value 6.1, not 5.

Can anyone explain why this happens?

Again this is ruby 1.8.6



------=_Part_1008_23213919.1205460801686-- ------=_Part_1007_33241428.1205460801685 Content-Type: text/x-diff; name=eval.c.diff Content-Transfer-Encoding: base64 X-Attachment-Id: f_fds46zsx0 Content-Disposition: attachment; filename=eval.c.diff SW5kZXg6IGV2YWwuYwo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLSBldmFsLmMJKHJldmlzaW9uIDE1NzY5KQorKysg ZXZhbC5jCSh3b3JraW5nIGNvcHkpCkBAIC0zMDM4LDEzICszMDM4LDE2IEBACiAJUkVUVVJOKFFm YWxzZSk7CiAKICAgICAgIGNhc2UgTk9ERV9JRjoKLQlFWEVDX0VWRU5UX0hPT0soUlVCWV9FVkVO VF9MSU5FLCBub2RlLCBzZWxmLAotCQkJcnVieV9mcmFtZS0+bGFzdF9mdW5jLAotCQkJcnVieV9m cmFtZS0+bGFzdF9jbGFzcyk7CiAJaWYgKFJURVNUKHJiX2V2YWwoc2VsZiwgbm9kZS0+bmRfY29u ZCkpKSB7CisJICAgIEVYRUNfRVZFTlRfSE9PSyhSVUJZX0VWRU5UX0xJTkUsIG5vZGUsIHNlbGYs CisJCQkgICAgcnVieV9mcmFtZS0+bGFzdF9mdW5jLAorCQkJICAgIHJ1YnlfZnJhbWUtPmxhc3Rf Y2xhc3MpOwogCSAgICBub2RlID0gbm9kZS0+bmRfYm9keTsKIAl9CiAJZWxzZSB7CisJICAgIEVY RUNfRVZFTlRfSE9PSyhSVUJZX0VWRU5UX0xJTkUsIG5vZGUsIHNlbGYsCisJCQkgICAgcnVieV9m cmFtZS0+bGFzdF9mdW5jLAorCQkJICAgIHJ1YnlfZnJhbWUtPmxhc3RfY2xhc3MpOwogCSAgICBu b2RlID0gbm9kZS0+bmRfZWxzZTsKIAl9CiAJZ290byBhZ2FpbjsK ------=_Part_1007_33241428.1205460801685--