2010-01-09 15 views
12

Jestem początkującym Rubinem. Z książki wiem, że nazwa metody Ruby powinna zaczynać się od małej litery lub podkreślenia. Ale znalazłem różne scenariusze:Co to są wielkie i małe litery nazwy metody ruby?

  1. Jeśli metoda jest zdefiniowana poza klasą, może rozpocząć się dopiero z małej litery, Ruby będzie narzekać z błędem, jeśli starają się określić metodę, która rozpoczyna się wielką literą, na przykład:

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

    ale poniższy kod nie działa:

    define SayHi 
        puts "Hello" 
    end 
    SayHi 
    

    będzie produkować błąd:

    :in `<main>': uninitialized constant SayHi (NameError) 
    
  2. Jeśli metoda jest zdefiniowana wewnątrz klasy, to może zaczynać się wielką literą:

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

Czy ktoś wie dlaczego # 1 nie działa podczas pracy # 2? Jakie są dokładne zasady nazwy metody ruby?

Odpowiedz

23

Zgodnie z konwencją rzeczy zaczynające się od wielkich liter to stałych. Po wywołaniu SayHi, mówisz Ruby, aby szukał stałej o tej nazwie. Oczywiście, że nie ma, więc nie.

Jeśli chcesz wywołać metodę, musisz dodać parę nawiasów. Na przykład:

def S 
    puts "shazam!" 
end 

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

Wewnątrz klasy zasady rozdzielczości są nieco inne. Zdefiniujmy prostą klasę ze stałą i metodę o nazwie wyglądać stałej:

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 

Teraz A pewnością jest stała. Ale co z 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. 

Więc nie jest to stała, tylko metoda o tej nazwie. Kiedy staramy się dostępem B z instancji C, obecnie Ruby szukasz sposobu:

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

Gdybyśmy chcieli uzyskać dostęp do stałą C zamiast używamy kwalifikator zakres :::

irb(main):012:0> C::A 
=> "x" 
+0

Dość nowe dla rubinu, a to jest również pomocne dla mnie. Wyjaśnione doskonale. +1 –

+0

Dzięki John, wiele się nauczyłem z twojej odpowiedzi. –

1

Nie rób niczego, co próbujesz zrobić. To zły styl kodowania.

Dobry Ruby styl kodowania:

def method_name 
end 

# or 

class CamelCase 
    def method_name(parameter_name) 
    end 
end 

Prawie wszystko inne jest po prostu błędne. Język może pozwolić ci robić inne rzeczy, ale to nie znaczy, że powinieneś.

Ponadto, ogólnie rzecz biorąc, nie chcesz definiować metod poza klasą lub modułem - jest to dopuszczalne w krótkich scenariuszach, ale nie w projektach merytorycznych.

+0

Może wyemitować "poza klasą" do "poza klasą lub modułem"? Nie * wszystko * ma sens w klasie - czasami masz pakiet metod, które pasują do siebie, ale nie masz powodu, aby tworzyć instancje dla tych metod. – Telemachus

+4

W rzeczywistości metody, które zaczynają się od wielkich liter są dość powszechne, a nawet część bibliotek rdzenia i standardowych bibliotek, na przykład metoda 'Array',' Hash', 'Integer',' Float', 'String' w bibliotece rdzenia oraz 'DelegateClass' w bibliotece' delegate'. Nie jest to wcale "zły styl kodowania", wręcz przeciwnie. Właściwie jest to właściwy sposób definiowania metod, które zwracają 'Class' es lub' Module's, które następnie mają być 'include'd,' extend' ed lub dziedziczone z. –

+0

To prawda, ale bądźmy szczerzy, nie są to typowe przypadki użycia. To jest nowy facet i nie zamierza pisać metod, które w najbliższym czasie zwrócą klasy lub moduły. Chociaż użyłem kilku z nich, nie sądzę, żebym znalazł jeszcze dobry powód, by napisać je samemu. –

Powiązane problemy