operators vs. methods

S

Sarah Allen

Today I was just re-reading introductory Ruby docs as I prepare to teach
a few newbies tomorrow and I find myself feeling newbie-ish.

On ruby-lang.org's Ruby from other languagage highlights
http://www.ruby-lang.org/en/documentation/ruby-from-other-languages/
it points out that a method call is really a message to another object:

# This
1 + 2
# Is the same as this ...
1.+(2)
# Which is the same as this:
1.send "+", 2

That's all well and good, except that + isn't an ordinary method. If I
take another method like div:

# This
4.div(2)
# Is not the same as
4 div 2

In fact the latter is a syntax error.

When I first learned Ruby I was led to believe that + is just a method
with a funny name, but now that I think about it that cannot be. Not
only is there a special way that spaces are handled, but operator
precedence is pretty special too.

Where might I find this behavior documented? Is there a special list of
operators? How are they different from methods? Can I create my own?

Puzzled, or maybe I just need more sleep,

Sarah
 
7

7stud --

Sarah said:
a method call is really a message to another object:

# This
1 + 2
# Is the same as this ...
1.+(2)
# Which is the same as this:
1.send "+", 2

That's all well and good, except that + isn't an ordinary method. If I
take another method like div:

# This
4.div(2)
# Is not the same as
4 div 2

In fact the latter is a syntax error.

When I first learned Ruby I was led to believe that + is just a method
with a funny name,

It is. As you've stated here:
# This
1 + 2
# Is the same as this ...
1.+(2)
# Which is the same as this:
1.send "+", 2

..and here is the proof:

class Fixnum
def +(val)
return "hello"
end
end

puts 1 + 2
puts 1.send("+", 2)

--output:--
hello
hello

Ruby gives you a choice with some methods, like +() and =(), to use a
special syntax. Special syntaxes are commonly known as "syntactic
sugar". What happens is that the "sugared syntax" is converted into
the normal method call, so:

1 + 2 becomes 1.+(2)

and

obj.x = 10 becomes obj.x=(10) (where the method name is 'x=')
 
S

Sarah Allen

7stud said:
Ruby gives you a choice with some methods, like +() and =(), to use a
special syntax. Special syntaxes are commonly known as "syntactic
sugar". What happens is that the "sugared syntax" is converted into
the normal method call, so:

1 + 2 becomes 1.+(2)

and

obj.x = 10 becomes obj.x=(10) (where the method name is 'x=')

So, where might I find a list of the special sugary methods? and may I
define my own? I know I can override + and =, but could I make ß or foo
be sent to an object with syntax such as 4 foo 4 or "test"ß"this" ? (I
don't know that I would want to, but I am curious)

Thanks,
Sarah
 
R

Robert Klemme

2009/8/25 Sarah Allen said:
So, where might I find a list of the special sugary methods?

There is a list in the printed edition of the Pickaxe IIRC.
and may I
define my own? =A0I know I can override + and =3D, but could I make =DF o= r foo
be sent to an object with syntax such as 4 foo 4 or "test"=DF"this" ? =A0= (I
don't know that I would want to, but I am curious)

You cannot as that would mean changing of the language's syntax.

Kind regards

robert


--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
7

7stud --

Sarah said:
So, where might I find a list of the special sugary methods?

I don't know.
and may I
define my own?

Not that I'm aware of. However, you can define your own parser to
replace the sugared syntax with a method call:

r3test.rb
------
class Apple
def shout(str)
puts "#{str.upcase}!!!"
end
end

a = Apple.new
a shout "hello" #<---'SUGARED' METHOD CALL
-----


----
class MyRubyParser
attr_reader :data, :results

def initialize(fname)
@data = File.open(fname).readlines
@results = []
end

def desugar(meth_name)
@data.each do |line|
line = line.chomp
result = line.gsub(/^(.+?) (#{meth_name}) (.+)$/, '\1.\2(\3)' )
results << result
end
end
end

parser = MyRubyParser.new("r3test.rb")
parser.desugar("shout")

program = parser.results.join("\n")
eval(program)

--output:--
HELLO!!!
 
E

Etienne Vallette d'osia

7stud said:
Ruby gives you a choice with some methods, like +() and =(), to use a
special syntax.

Just to be clear, =() can't be used as a method name, you must add a
name ( x=() )
a.b = 2 calls the method "b=" of the object a : a.send("b=", 2)
a = 2 gives the name "a" to the object "2".

"a = 2" can't affect the old object names "a" (ruby != C++)



Sarah said:

"4 div 2" means "4(div(2))"

note: The operators can't be used as variable names, so there is no risk
"var + 3" means "var(+, 3)", that is no valid ruby.


Just for fun:

I think it can be possible to create a dsl to do what you want:
- method_missing create objects (I will call them Flux)
that keep its name and argument
- if the name of the method is also the name of an existing variable,
and the argument is a Flux,
then it call the stored method with variable and the stored argument
So "var div 2" means Flux.new:)div, 2).call(var) which means
"var.send:)div,2)"
But there are many limitations (for instance, "4" is not a valid method
name)
 
7

7stud --

Robert said:
There is a list in the printed edition of the Pickaxe IIRC.

Ah, yes. p. 339 (pickaxe2). The ones with check marks preceding them
in the operator table.

In order of precedence(highest at the top):

[] []=
**
! ~ + - (unary plus and minus, e.g. -1)
* / %
+ -&
^ |
<= < > >=
<=> == === != =~ !~
 
B

Brian Candler

7stud said:
There is a list in the printed edition of the Pickaxe IIRC.

Ah, yes. p. 339 (pickaxe2). The ones with check marks preceding them
in the operator table.

In order of precedence(highest at the top):

[] []=
**
! ~ + - (unary plus and minus, e.g. -1)
* / %
+ -&
^ |
<= < > >=
<=> == === != =~ !~

Note that the majority of these call a method whose symbolic name is the
same as the operator itself, but there are some exceptions:

(1) unary plus and unary minus are :+@ and :-@
=> -3

(2) !~ and != operators do not map directly to method calls, but call
:=~ and :== and negate the answers
== x
=> nil== x
=> true

I have written programs which use x.send:)[]=, val). I call this smiley
programming :-@
 
D

David Masover

Seems your question has been answered already, but I couldn't resist jumping
in...

a method call is really a message to another object:

# This
1 + 2
# Is the same as this ...
1.+(2)
# Which is the same as this:
1.send "+", 2

# Which is the same as this, but more efficient:
1.send :+, 2

Any method you try to call will have its name converted into a symbol anyway,
so that is both slightly faster and slightly quicker to type. Probably doesn't
matter here, but I consider it good style.
# This
4.div(2)
# Is not the same as
4 div 2

That is true, and other people have already mentioned that it's syntactic
sugar. However, this isn't as much a limitation as you might think. As 4 is
not a method, I can't make the above work, but it's certainly possible to do
something like this:

foo div 2

Just look at rspec for some ideas... Probably not a beginner topic, though.
 
J

Justin Collins

Brian said:
I have written programs which use x.send:)[]=, val). I call this smiley
programming :-@

Why would you do that, though?

irb(main):001:0> class A
irb(main):002:1> def []= index, value
irb(main):003:2> puts "Index: #{index} Value: #{value}"
irb(main):004:2> end
irb(main):005:1> end
=> nil
irb(main):006:0> A.new[1] = "hello"
Index: 1 Value: hello
=> "hello"

Is it because you only want to send a single value with no index?

-Justin
 
B

Brian Candler

Justin said:
Why would you do that, though?

There was a good reason why I needed to do send:)[]=, ...) but I can't
remember it off-hand. It may have been a variable-sized set of
arguments, or perhaps a private method.
 
O

Omran Nazir

Err, Hi Sarah,=0A=0AWell i'm a newbie to fresh out of the womb in fact but =
i think i can point you in the right direction. Firstly yes operators are i=
mplemented as methods so 1+2 would be interpreted as 1.+(2) and since they =
are methods there behavoiur for classes that you create can be specified by=
you. Operators do also have a precedence as operators do in C and are meth=
ods of all objects of the Numeric Class.=0A=0AFrom what I understand 'div' =
and '/' and not exactly the same. So 1/2 would be seen as 1./(2) whereas if=
you used 'div', you would write 1.div(2). The operator '/' seems to be equ=
ipt to deal with spaces but not 'div', that is probaly why you would use '(=
)' to pass the argument. You also have 'fdiv' for floating point division a=
nd 'quo' returns a rational where possible.=0A=0AThis exact topic if covere=
d in glorious technicolour in 'The Ruby Programming Language' by Flanagan a=
nd Matsumoto, but I am sure you can google it also.=0A=0A Imran Nazir =0A=
=0A=0AFriend, Boho, House Owner, Citizen, Engineer=0A=0A=0A=0A=0A=0A_______=
_________________________=0AFrom: Sarah Allen <[email protected]>=0ATo:=
ruby-talk ML <[email protected]>=0ASent: Tue, 25 August, 2009 8:06:2=
6=0ASubject: operators vs. methods=0A=0AToday I was just re-reading introdu=
ctory Ruby docs as I prepare to teach=0Aa few newbies tomorrow and I find m=
yself feeling newbie-ish.=0A=0AOn ruby-lang.org's Ruby from other languagag=
e highlights=0Ahttp://www.ruby-lang.org/en/documentation/ruby-from-other-la=
nguages/=0Ait points out that a method call is really a message to another =
object:=0A=0A# This=0A1 + 2=0A# Is the same as this ...=0A1.+(2)=0A# Which =
is the same as this:=0A1.send "+", 2=0A=0AThat's all well and good, except =
that + isn't an ordinary method. If I=0Atake another method like div:=0A=
=0A# This=0A4.div(2)=0A# Is not the same as=0A4 div 2=0A=0AIn fact the latt=
er is a syntax error.=0A=0AWhen I first learned Ruby I was led to believe t=
hat + is just a method=0Awith a funny name, but now that I think about it t=
hat cannot be. Not=0Aonly is there a special way that spaces are handled, =
but operator=0Aprecedence is pretty special too.=0A=0AWhere might I find th=
is behavior documented? Is there a special list of=0Aoperators? How are t=
hey different from methods? Can I create my own?=0A=0APuzzled, or maybe I =
just need more sleep,=0A=0ASarah=0A-- =0APosted via http://www.ruby-forum.c=
om/.=0A=0A=0A
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,071
Latest member
MetabolicSolutionsKeto

Latest Threads

Top