From: Ryan Davis Date: 2010-02-19T08:18:28+09:00 Subject: Re: Ruby conditionals subtlety? On Feb 18, 2010, at 13:44 , Farhad Farzaneh wrote: > Ryan Davis wrote: >> On Feb 18, 2010, at 11:49 , Farhad Farzaneh wrote: >> >>> Hi, >>> >>> Anyone know why thse two forms of "unless" behave differently? >>> >>>> irb >>> irb(main):001:0> foo = true unless defined?(foo) >>> => nil >>> irb(main):002:0> unless defined?(fooo) ; fooo = true ; end >>> => true >> >> oddity in the way the code is parsed: >> >> % echo "foo = true unless defined?(foo)" | parse_tree_show >> s(:if, s(:defined, s(:lvar, :foo)), nil, s(:lasgn, :foo, s(:true))) >> >> % echo "unless defined?(fooo) ; fooo = true ; end" | parse_tree_show >> s(:if, s(:defined, s(:call, nil, :fooo, s(:arglist))), nil, s(:lasgn, >> :fooo, s(:true))) > > Cool, any chance you could give a short description for those of us that > have never really thought about the parser or used parse_tree_show? Your latter code snippet treats "fooo" in defined? as a method call. This is because the assignment inside the conditional hasn't been parsed yet, and hasn't affected the lookup tables. The former doesn't have this problem because the body of the conditional is parsed first.