On Wed, Apr 09, 2003 at 07:18:39AM +0900, Daniel Carrera wrote:
> One of the things I like about Ruby is that it can use ! and ? in method 
> names.  However, it seems that there are still limits to what can be 
> done.
> 
> I need a 'factorial' method, and I thought it'd be cute if the syntax was 
> "n.!" because it's so close to "n!".  But Ruby doesn't let me do that.
> 
> # This one works:
> >> class Fixnum
> >>     def f  # Factorial 
> >>         self < 0 and return -1  # Error code.
> >>         self ==0 and return  1 
> >>         self * (self-1).f
> >>     end
> >> end
> >> 5.f
> => 120
> 
> This is cool.  But it'd be cooler if I could write 'def !' and '5.!'.
> But 'def !' causes a parse error.
> 
> Now my question:
> Does anyone know why 'def !' causes a parse error?

There's a workaround:

batsman@kodos:/tmp$ expand -t2 a.rb
class Fixnum
  def fact
    self < 0 and return -1  # Error code.
    self ==0 and return  1
    self * (self-1).fact
  end
  alias_method "!", :fact
end
p Fixnum.instance_methods.sort

batsman@kodos:/tmp$ ruby a.rb
["!", "%", "&", "*", "**", "+", "-", "-@", "/", "<", "<<", "<=", "<=>",
"==", ">", ">=", ">>", "[]", "^", "abs", "divmod", "downto", "fact",
"id2name", "modulo", "next", "size", "step", "succ", "times", "to_f",
"to_s", "type", "upto", "zero?", "|", "~"]

However...
batsman@kodos:/tmp$ expand -t2 a.rb
class Fixnum
  def fact
    self < 0 and return -1  # Error code.
    self ==0 and return  1
    self * (self-1).fact
  end
  alias_method "!", :fact
end
p Fixnum.instance_methods.sort
p 5.!
batsman@kodos:/tmp$ ruby a.rb
a.rb:10: parse error

I've been reading parse.y for a while and see no way '!' could be used
as an identifier alone, Ruby will try to begin an expression using
 expr := '!' command_call
or an argument with
 arg := '!' arg


-- 
 _           _                             
| |__   __ _| |_ ___ _ __ ___   __ _ _ __  
| '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \ 
| |_) | (_| | |_\__ \ | | | | | (_| | | | |
|_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_|
	Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Linux: because a PC is a terrible thing to waste
	-- ksh / cis.ufl.edu put this on Tshirts in '93