tags:

views:

290

answers:

3

I am a ruby beginner. From the book, I know that ruby method name should start with a lowercase letter ( or underscore). But I found different scenarios:

  1. if a method is defined outside a class, it can only begin with lowercase letter, Ruby will complain error if you try to define a method which begin with uppercase letter, for example:

    define sayHi
     puts "Hello" 
    end
    sayHi   # => Hello
    

    but, the following code is not working:

   define SayHi
     puts "Hello" 
    end
    SayHi 

   it will produce error:
   :in `': uninitialized constant SayHi (NameError)
   
  1. If a method is defined inside a class, then it can begin with uppercase letter:
     class Test
       def SayHi
        puts "hello" 
       end
     end
     t = Test.new
     t.SayHi    # => hello
     

Does anyone know why #1 does not work while #2 work? What are the exact rules the ruby method name?

A: 

the folloing links should answer your questions:

http://www.softiesonrails.com/2007/10/18/ruby-101-naming-conventions

http://itsignals.cascadia.com.au/?p=7

kon
+7  A: 

By convention, things that start with uppercase letters are constants. When you invoke SayHi, you're telling Ruby to look for a constant with this name. Of course, there isn't one, so it fails.

If you want to invoke the method, you'll need to add a pair of parentheses. For example,

def S
  puts "shazam!"
end

S    #=> NameError: uninitialized constant S
S()  #=> "shazam!"

Inside of a class, the resolution rules are a little different. Let's define a simple class with a constant and a method named to look like a constant:

irb(main):001:0> class C
irb(main):002:1>   A = "x"
irb(main):003:1>   def B
irb(main):004:2>     puts "B() invoked"
irb(main):005:2>   end
irb(main):006:1> end
=> nil

Now, A is certainly a constant. But what about B?

irb(main):008:0> C.const_defined?("A")
=> true    # A is a constant!
irb(main):009:0> C.const_defined?("B")
=> false   # B looks like a constant but isn't, because we
           # used "def" to create it. "def" is for methods,
           # not constants.

So it isn't a constant, just a method with that name. When we try to access B from an instance of C, now Ruby's looking for a method:

irb(main):011:0> C.new.B
B() invoked
=> nil

If we wanted to access a constant of C instead, we use the scope qualifier :::

irb(main):012:0> C::A
=> "x"
John Feminella
Fairly new to ruby, and this is helpful to me as well. Excellently explained. +1
Steve B.
Thanks John, I learned a lot from your answer.
Steve Zhang
+1  A: 

Don't do any of what you're trying to do. It's bad coding style.

Good Ruby coding style:

def method_name
end

# or

class CamelCase
  def method_name(parameter_name)
  end
end

Almost anything else is simply wrong. The language might let you do other stuff, but that doesn't mean you should.

Also, generally you don't want to be defining methods outside of a class or module — that's acceptable in short throw-away scripts, but not in projects of substance.

Bob Aman
Maybe emend "outside of a class" to "outside of a class or module"? Not *everything* makes sense in a class - sometimes you have a bundle of methods that fit together, but you have no reason to make instances for those methods.
Telemachus
Actually, methods that begin with uppercase letters are quite common and even part of the core libraries and standard libraries, for example the `Array` method, `Hash`, `Integer`, `Float`, `String` in the core library and `DelegateClass` in the `delegate` library. It is not at all "bad coding style", quite the opposite actually. It's actually the proper way to define methods which return `Class` es or `Module` s, which are then intended to be `include` d, `extend` ed or inherited from.
Jörg W Mittag
True, but let's be clear though, those are not common use-cases. This is a new guy, and he's no going to be writing methods that return classes or modules anytime soon. While I've used a few of those, I don't think I've yet found a good reason to write one myself.
Bob Aman
Hi, Mr Adam, that is true that I am new guy for Ruby, I already know it is not a good coding convention, I want to clarify that I am not trying to do the 'bad coding style', but I am trying to understand the reason behind it. If the statement of what you mentioned about 'bad style' is true, then it should not be allowed to use anywhere in ruby, and there should be no reason to make exception to break the bad style because it is bad style. But unfortunately it is not true.
Steve Zhang
Ruby doesn't hold your hand — it assumes you're an adult, and you know what you're doing. Even Python doesn't do this.
Bob Aman