Каковы прописные и строчные правила имени метода ruby?
Я начинающий Ruby. Из книги я знаю, что имя метода Ruby должно начинаться со строчной буквы или подчеркивания. Но я нашел разные сценарии:
Если метод определен вне класса, он может начинаться только со строчной буквы, Ruby будет выдавать ошибку с ошибкой, если вы попытаетесь определить метод, который начинается с заглавной буквы, например:
define sayHi puts "Hello" end sayHi # => Hello
но следующий код не работает:
define SayHi puts "Hello" end SayHi
это выдаст ошибку:
:in `<main>': uninitialized constant SayHi (NameError)
Если метод определен внутри класса, он может начинаться с заглавной буквы:
class Test def SayHi puts "hello" end end t = Test.new t.SayHi # => hello
Кто-нибудь знает, почему № 1 не работает, а № 2 работает? Каковы точные правила имени метода ruby?
2 ответа
По соглашению, вещи, которые начинаются с заглавных букв, являются константами. Когда вы вызываете SayHi
, вы говорите Руби искать константу с этим именем. Конечно, его нет, поэтому он терпит неудачу.
Если вы хотите вызвать метод, вам нужно добавить пару скобок. Например,
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
Сейчас Руби ищет метод:
irb(main):011:0> C.new.B
B() invoked
=> nil
Если бы мы хотели получить доступ к константе C
вместо этого мы используем спецификатор области ::
:
irb(main):012:0> C::A
=> "x"
Не делай ничего из того, что ты пытаешься сделать. Это плохой стиль кодирования.
Хороший стиль кодирования Ruby:
def method_name
end
# or
class CamelCase
def method_name(parameter_name)
end
end
Почти все остальное просто неправильно. Язык может позволить вам делать другие вещи, но это не значит, что вы должны.
Кроме того, как правило, вы не хотите определять методы вне класса или модуля - это приемлемо в коротких одноразовых скриптах, но не в проектах по существу.