From: Albert Schlef on
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
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
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
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
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