From: Albert Schlef on 31 Dec 2009 04:44 Seebs wrote: > On 2009-12-31, Albert Schlef <albertschlef(a)gmail.com> wrote: >> So it seems Ruby internally recognizes some structures as "statemenets" >> and others as "expressions". It seems disapointing at first, but since >> Ruby supports precedence for operators (something Lisp doesn't), there >> has to be some price to pay. > > I don't think that's it at all. I think it's that methodname( is a > method > call (), not a grouping (). Thus the difference between > puts(a or b) > and > puts (a or b) > > In short, it's nothing to do with statements-vs-expressions, and > everything > to do with disambiguating method calls vs. parenthesized expressions. I don't think there's a disagreement between us: Here is a method call in Ruby: method_name ARG , ARG , ARG , .... ARG can be the expression "2", for example. But is can't be the expression "2 or 3". So the compiler has to classify "2 or 3" as something that can't stand for an ARG. So the compiler classifies it as a STATEMENET and decides that a STATEMENT can stand for an ARG. BTW, I can imagine why "2 or 3" couldn't be a method argument. This would only be possible if "or" has higher precedence than ",", or else `func(1, 2 or 3, 4) would wreak havoc. But then `do_this() or a, c = d, e` would fail, because it'd mean `(do_this() or a), c = d, e`. -- Posted via http://www.ruby-forum.com/.
From: Albert Schlef on 31 Dec 2009 04:51 Phillip Gawlowski wrote: > On 31.12.2009 10:31, Albert Schlef wrote: > >> Then why does the following work? >> >> a = (123 if true) > > Because here you do an assignment. My, my, my. I can do this: a = 999 and I can do this: a = (123 if true) so doens't this mean that wherever I can put "999" I can also put "(123 if true)"? In other words, why can I do this: puts 999 But I *can't* do this: puts (123 if true) ??? -- Posted via http://www.ruby-forum.com/.
From: Albert Schlef on 31 Dec 2009 04:54 Albert Schlef wrote: > [...]So the compiler has to classify "2 or 3" as > something that can't stand for an ARG. So the compiler classifies it as > a STATEMENET and decides that a STATEMENT can stand for an ARG. Oops. I meant "that a STATEMENT *can't* stand for an ARG." -- Posted via http://www.ruby-forum.com/.
From: Marnen Laibow-Koser on 31 Dec 2009 04:59 Albert Schlef wrote: > Albert Schlef wrote: >> Well. it turns out there aren't that many ways in ruby. >> >> I originally tried to do the following: >> >> some_func(ARGV[0] or raise "You must provide an argument") >> >> I wish it worked. But it doesn't. So I changed it to: >> >> some_func(ARGV[0] || raise "You must provide an argument") >> >> It still didn't work. So finally I did: >> >> some_func(ARGV[0] || (raise "You must provide an argument")) >> >> It works. But, I must say, it isn't as beautiful as my original plan. It >> doesn't read as English. > > Hey, I now see that this works: > > some_func((ARGV[0] or raise "You must provide an argument")) > > Great. On the other hand, I won't be able to remember this the next time > I need it. Just use Ruby's rescue syntax instead of trying to be clever. Best, -- Marnen Laibow-Koser http://www.marnen.org marnen(a)marnen.org -- Posted via http://www.ruby-forum.com/.
From: Phillip Gawlowski on 31 Dec 2009 05:02
On 31.12.2009 10:51, Albert Schlef wrote: > My, my, my. > > I can do this: > > a = 999 > > and I can do this: > > a = (123 if true) > > so doens't this mean that wherever I can put "999" I can also put "(123 > if true)"? Note: I'm dumbing this down as much as I can (from my limited understanding of Ruby internals), so no offense if I treat you like a child, that's not my intention, and serves to make the issue understandable. :) Since it's an if statement, you probably can. In this case, since 123 is always true, Ruby can "ignore" the "if true" bit (kinda, sorta). > In other words, why can I do this: > > puts 999 > > But I *can't* do this: > > puts (123 if true) Because puts takes an argument, not a statement (basically). The problem with computers is that they are stupid. It is obvious, to you, that you *mean* "output 123, if 123 is true". However, Ruby cannot understand intent. It sees "output (123 if true). Wait, I can't handle that, let me tell the smart guy about that, so that he can explain it really slow for me." This is an effect of multiple issues: Precedence, optimizations done by the interpreter (compiler, if you want), and the conflict of statement vs expression ("if" is a statement, "123 if true" is an expression for the purpose of this explanation). So, in a nutshell: Ruby throws up its arms, because it cannot understand what you want. That's why "puts 123 if true", "(puts 123) if true" both work, but "puts (123 if true)" doesn't. Kinda. -- Phillip Gawlowski |