Каковы прописные и строчные правила имени метода ruby? - PullRequest
16 голосов
/ 09 января 2010

Я новичок в Ruby. Из книги я знаю, что имя метода Ruby должно начинаться со строчной буквы или подчеркивания. Но я нашел разные сценарии:

  1. Если метод определен вне класса, он может начинаться только с строчной буквы, Ruby будет выдавать ошибку, если вы попытаетесь определить метод, который начинается с заглавной буквы, например:

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

    но следующий код не работает:

    define SayHi
      puts "Hello" 
    end
    SayHi 
    

    выдаст ошибку:

    :in `<main>': uninitialized constant SayHi (NameError)
    
  2. Если метод определен внутри класса, он может начинаться с заглавной буквы:

    class Test
      def SayHi
        puts "hello" 
      end
    end
    t = Test.new
    t.SayHi    # => hello
    

Кто-нибудь знает, почему # 1 не работает, пока # 2 работает? Каковы точные правила имени метода ruby?

Ответы [ 2 ]

27 голосов
/ 09 января 2010

По соглашению, заглавные буквы начинаются с константы . Когда вы вызываете SayHi, вы говорите Ruby искать константу с этим именем . Конечно, его нет, поэтому он терпит неудачу.

Если вы хотите вызвать метод, вам нужно добавить пару скобок. Например,

def S
  puts "shazam!"
end

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

Внутри класса правила разрешения немного отличаются. Давайте определим простой класс с константой и именем метода, который будет выглядеть как константа:

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

Теперь A, безусловно, является константой. Но как насчет 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.

Так что это не константа, это просто метод с таким именем. Когда мы пытаемся получить доступ к B из экземпляра C, теперь Ruby ищет метод:

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

Если мы хотим получить доступ к константе C, мы используем квалификатор области :::

irb(main):012:0> C::A
=> "x"
1 голос
/ 09 января 2010

Не делай того, что пытаешься сделать. Это плохой стиль кодирования.

Хороший стиль кодирования Ruby:

def method_name
end

# or

class CamelCase
  def method_name(parameter_name)
  end
end

Почти все остальное просто неправильно. Язык может позволить вам делать другие вещи, но это не значит, что вы должны.

Кроме того, как правило, вы не хотите определять методы вне класса или модуля - это приемлемо в коротких одноразовых скриптах, но не в проектах по существу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...