David A. Black wrote:
> Here's another interesting space/non-space case:>> >> def m(*args); "hi"; end> => nil> >> m *10> => "hi"> >> m * 10> => "hihihihihihihihihihi">> In m *10 the * is the unary *, while in m * 10 it's the infix> operator/method *.>>> David
And what, may I ask, it the unary * operator? Is it what I've heard
Rubyists call the "splat" operator that you use in var args? How and
why would you override it?
Thanks so much for indulging my pursuit of arcane Ruby knowledge :)
Sarah

On Apr 14, 2010, at 3:47 PM, Sarah Allen wrote:
>> end> is the same as...?> know> 2 is a FixNum, but why is that significant? Specifically, how is the> expression evaluated to make 1 +1 work?
From your original,
Time.now -t
now is a method call
1 -t
1 is not a method call
> from (irb):19
There's no coerce method for a Time instance.
Try this:
t = Time.now
1 + t
Then do:
class Time
def coerce(other)
case other
when Integer
return other, self.to_i
else
super
end
end
end
And retry:
1 + t
This is a different issue than the parser trying to apply :+@
-Rob
>>> Thanks!> Sarah> --> Posted via http://www.ruby-forum.com/.>
Rob Biedenharn http://agileconsultingllc.com
Rob@AgileConsultingLLC.com

Zach Moazeni wrote:
> Time.now -t # executed as (Time.now) -t or t.send(:-@) which doesn't> exist> Time.now -t # is trying to do:> Time.now(-t) # which first needs to evaluate -t first (... which is> t.send(:-@) ...)
I should proofread more. The more I look at it, I think the second is
right.
--
Zach Moazeni
http://simplechatter.com

Sarah Allen wrote:
>>> 1 + 1> is the same as>>> 1.send(:+, 1)
Yes.
>>> 1 +1> is the same as...?
Same again, as you have shown.
> So, in what way is 1 +2 not like 1 +t (where t is a Time object).
Well, it must be either
(1) + (t)
or
(1) (+t)
The Ruby parser is picking the second, even though it doesn't make sense
at a higher level (you can't have two adjacent expressions without an
intervening operator)
That doesn't explain why 1 +2 is treated differently though.
Actually, there is an optimisation that numeric literals have any unary
prefix interpreted by the parser. That is, +1 is the value +1, not 1
with a unary plus applied.
You can demonstrate it thus:
>> class Integer>> def +@>> puts "Whee!">> self>> end>> end
=> nil
>> +1
=> 1
>> +(1)
Whee!
=> 1
>>
(BTW, I don't recommend redefining core class operators like this. If
you redefine Fixnum#+, and don't preserve its existing semantics, nasty
things will happen)
The first case doesn't invoke the unary plus method, it's just absorbed
into the literal number.
So you'd think even more that 1 +1 would be taken as two adjacent
integers, like 1 1 or 1 +t. Clearly, it isn't.
Welcome to Ruby. It's like your granny - it might have some warts, but
it's an old friend.

Hi --
On Wed, 14 Apr 2010, Sarah Allen wrote:
>> In m *10 the * is the unary *, while in m * 10 it's the infix>> operator/method *.>>>>>> David>> And what, may I ask, it the unary * operator? Is it what I've heard> Rubyists call the "splat" operator that you use in var args? How and> why would you override it?
It is indeed what people call the "splat" operator, though I've never
found that name very expressive. I think of it as the unar[r]ay
operator (that's unary unarray :-) It does an "unarray" operation in
the sense that it can turn an array into a bare list, in a method
call.
You can't define it directly (I believe that's true in 1.9 as well as
earlier versions), but you can affect what it does via the #to_a
method:
o = Object.new
def o.to_a; [1,2,3]; end
a = *o
p a # [1,2,3]
As for the why: I don't think you'd often define #to_a just to get *
behavior. It's more of an extra thing you get in cases where you need
#to_a anyway.
David