From: Albert Schlef on
Phillip Gawlowski wrote:
> On 31.12.2009 10:51, Albert Schlef wrote:
>> 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).

Then why can I do this?

puts (123 or true)

Are you going to tell me that "123 or true", unlike "123 if true",
*isn't* a statement?

If "123 or true" isn't a statement, then it's a simple expression. And
then I would be able to do:

puts(123 or true) # Note: no space before parentheses

But I can't! So it follows that "123 or true" too is a statement.

Let me sum it up:

puts (123 if true) # Syntax error.

puts (123 or true) # Works.

Although both are "statements".

>
> The problem with computers is that they are stupid. It is obvious, to
> you, that you *mean* "output 123, if 123 is true".

No, no, no. By `puts (123 if true)` I mean: output the result of `123 if
true`.
--
Posted via http://www.ruby-forum.com/.

From: Albert Schlef on
Marnen Laibow-Koser wrote:
> Albert Schlef wrote:
>> Albert Schlef wrote:
>>
>> 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.

What do you mean?
--
Posted via http://www.ruby-forum.com/.

From: Phillip Gawlowski on
On 31.12.2009 11:35, Albert Schlef wrote:
> Then why can I do this?
>
> puts (123 or true)
>
> Are you going to tell me that "123 or true", unlike "123 if true",
> *isn't* a statement?

I'm afraid I am. It's an evaluation. Boolean evaluation (with "and" /
"or" having lower precedence than && / ||).

> If "123 or true" isn't a statement, then it's a simple expression. And
> then I would be able to do:

Take a third option: It's an evaluation. ;)


Crash course in Boolean logic:

We have two items A and B.

Case "AND":
return true if, and only if, both "a" *and* "b" are true.

Example:
irb(main):004:0> a, b = true, true
=> [true, true]
irb(main):005:0> a and b
=> true
irb(main):006:0> b = false
=> false
irb(main):007:0> a and b
=> false
irb(main):008:0>

As you see, the evaluation spits back a result: True, if both "a" and
"b" are true, false if only "a" or "b" is true.

Case "OR":
return true if *either* "a" *or* "b" are true

Example:
irb(main):008:0> a, b = false, false
=> [false, false]
irb(main):009:0> a or b
=> false
irb(main):010:0> a = true
=> true
irb(main):011:0> a or b
=> true
irb(main):012:0> b = false
=> false
irb(main):013:0> a or b
=> true

As you can see, if both "a" and "b" are false, the evaluation returns
false ("returns false" meaning "the result is false").
If either "a" *or* "b" are true, the evaluation returns true.
Same if both "a" *and* "b" are true.

> No, no, no. By `puts (123 if true)` I mean: output the result of `123 if
> true`.

That's what I said, I was just verbose about it. ;)

--
Phillip Gawlowski

From: Robert Klemme on
On 12/31/2009 03:43 AM, Seebs wrote:
> On 2009-12-31, Phillip Gawlowski <pg(a)thimian.com> wrote:
>> Hm, on Ruby 1.9.1 I get:
>> irb(main):001:0> puts nil or 4
>>
>> => 4
>
> Note that this is equivalent to "puts nil" followed by "4".
>
> That's significant.
>
> Consider:
> irb(main):001:0> x = nil or 4
> => 4
> irb(main):002:0> x
> => nil
>
> The grouping is:
> (x = nil) or (4)
>
> Or
> (puts nil) or (4)
>
>> This seems like a bug to me, since parenthesis *should* "only" make
>> method calls and precedent unambigious.
>
> I believe that's precisely the problem -- the precedence of "or" is
> low enough that it can't occur inside a method argument.
>
> Compare this with the similar situation in C, where a comma operator
> cannot occur inside an argument list for a function, because it's part
> of the function-call syntax. So:
>
> valid C:
> x = 1, y = 2;
>
> (this performs both assignments, and returns the value of y after the
> assignment, which happens to be 2.)
>
> printf("%d\n", x = 1, y = 2);
>
> This probably prints 1, but I think it's undefined behavior because there's
> excess arguments to printf. (I'm not sure whether that's permitted or not,
> but my guess would be "no, but it probably always works".)
>
> So try:
>
> irb(main):003:0> puts( (nil or 4) )
> 4
> => nil
>
> Basically, if you really want parentheses (as in the precedence-changing
> operator), you need to include them... Not merely put something that can't
> go in a method argument list inside the confusingly-similar-looking
> () which surround method arguments.

And you can even omit the method brackets as in

irb(main):001:0> puts (nil or 4)
4
=> nil

Kind regards

robert



--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
From: Phillip Gawlowski on
On 31.12.2009 11:38, Albert Schlef wrote:

> What do you mean?

Something like this:
PS C:\Scripts> ruby .\unless.rb
we had an argument error
PS C:\Scripts> ruby .\unless.rb arg
arg
PS C:\Scripts> cat .\unless.rb
begin
raise ArgumentError unless ARGV[0]
puts ARGV[0]
rescue ArgumentError
puts "we had an argument error"
end

Basically, the begin/rescue/end tokens (bits that Ruby understands
without being told about by you) allow the programmer to recover from an
error in a graceful way.

If you had a file open, for example, you can make sure it is closed
properly if a so-called exception (Like ArgumentError in the example)
appears.

--
Phillip Gawlowski