2010-01-09 27 views
12

Tôi là người mới bắt đầu học Ruby. Từ cuốn sách, tôi biết rằng một tên phương thức Ruby nên bắt đầu bằng một chữ thường hoặc dấu gạch dưới. Nhưng tôi thấy kịch bản khác nhau:Quy tắc chữ hoa và chữ thường của tên phương thức ruby ​​là gì?

  1. Nếu một phương pháp được định nghĩa bên ngoài một lớp học, nó chỉ có thể bắt đầu bằng chữ cái viết thường, Ruby sẽ phàn nàn với một lỗi nếu bạn cố gắng để xác định một phương pháp mà bắt đầu bằng một chữ cái viết hoa, ví dụ:

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

    nhưng, đoạn code sau không làm việc:

    define SayHi 
        puts "Hello" 
    end 
    SayHi 
    

    nó sẽ tạo ra một lỗi:

    :in `<main>': uninitialized constant SayHi (NameError) 
    
  2. Nếu một phương pháp được định nghĩa bên trong một lớp học, sau đó nó có thể bắt đầu bằng chữ cái in hoa:

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

Có ai biết tại sao # 1 không hoạt động trong khi # 2 làm việc? Các quy tắc chính xác tên phương pháp ruby ​​là gì?

Trả lời

23

Theo quy ước, những thứ bắt đầu bằng chữ hoa là hằng số. Khi bạn gọi SayHi, bạn đang yêu cầu Ruby tìm kiếm một hằng số với tên này. Tất nhiên, không có một, vì vậy nó không thành công.

Nếu bạn muốn gọi phương thức, bạn sẽ cần phải thêm một cặp dấu ngoặc đơn. Ví dụ:

def S 
    puts "shazam!" 
end 

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

Bên trong lớp học, quy tắc giải quyết hơi khác một chút. Hãy xác định một lớp đơn giản với hằng số và một phương thức có tên giống như một hằng số:

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 

Bây giờ, A chắc chắn là một hằng số. Nhưng còn khoảng B thì sao?

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. 

Vì vậy, nó không phải là hằng số, chỉ là một phương pháp có tên đó. Khi chúng tôi cố gắng truy cập B từ một thể hiện của C, bây giờ Ruby tìm kiếm một phương pháp:

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

Nếu chúng ta muốn truy cập vào một hằng số của C thay vào đó, chúng tôi sử dụng phạm vi vòng loại :::

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

Khá mới đối với ruby ​​và điều này cũng hữu ích đối với tôi. Xuất sắc giải thích. +1 –

+0

Cảm ơn John, tôi đã học được rất nhiều từ câu trả lời của bạn. –

1

Đừng làm bất cứ điều gì bạn đang cố gắng làm. Đó là phong cách mã hóa xấu.

tốt của Ruby phong cách mã hóa:

def method_name 
end 

# or 

class CamelCase 
    def method_name(parameter_name) 
    end 
end 

Hầu như bất cứ điều gì khác chỉ đơn giản là sai. Ngôn ngữ có thể cho phép bạn làm những thứ khác, nhưng điều đó không có nghĩa là bạn nên làm.

Ngoài ra, nói chung bạn không muốn định nghĩa các phương thức bên ngoài một lớp học hoặc mô-đun - đó là chấp nhận được trong các tập lệnh vứt bỏ ngắn, nhưng không được chấp nhận trong các dự án về chất.

+0

Có thể phát ra "bên ngoài lớp" thành "bên ngoài lớp học hoặc mô-đun"? Không * mọi thứ * có ý nghĩa trong một lớp - đôi khi bạn có một bó các phương thức phù hợp với nhau, nhưng bạn không có lý do gì để tạo ra các cá thể cho các phương thức đó. – Telemachus

+4

Thực ra, các phương thức bắt đầu bằng chữ in hoa khá phổ biến và thậm chí là một phần của thư viện lõi và thư viện chuẩn, ví dụ phương thức 'Array',' Hash', 'Integer',' Float', 'String' trong thư viện lõi và 'DelegateClass' trong thư viện' delegate'. Nó không phải là ở tất cả "phong cách mã hóa xấu", hoàn toàn ngược lại thực sự. Nó thực sự là cách thích hợp để định nghĩa các phương thức trả về 'Lớp' hoặc 'Mô-đun', mà sau đó được dự định là' include' d, 'extend' ed hoặc được kế thừa từ. –

+0

Đúng, nhưng hãy rõ ràng, đó không phải là trường hợp sử dụng phổ biến. Đây là một anh chàng mới, và anh ấy sẽ không viết các phương thức trả lại các lớp học hoặc các mô-đun bất cứ lúc nào sớm. Trong khi tôi đã sử dụng một vài trong số đó, tôi không nghĩ mình chưa tìm được lý do chính đáng để viết một bản thân. –

Các vấn đề liên quan