2012-05-21 31 views
7

Tôi mới sử dụng Ruby. Tôi quen thuộc với một số ngôn ngữ khác. Câu hỏi của tôi là về phương pháp gọi không đúng thứ tự. Ví dụ:Làm cách nào để xử lý Lệnh Phương thức trong Ruby?

def myfunction 
    myfunction2 
end 

def myfunction2 
    puts "in 2" 
end 

Làm cách nào tôi có thể gọi myfunction2 trước khi được khai báo? Một số ngôn ngữ cho phép bạn khai báo ở đầu hoặc trong tệp .h. Ruby xử lý nó như thế nào?

Tôi luôn luôn cần phải làm theo điều này:

def myfunction2 
    puts "in 2" 
end 

def myfunction 
    myfunction2 
end 

Chủ yếu này tôi lỗi khi tôi cần phải gọi phương pháp khác bên trong def initialize cho một lớp.

Trả lời

18

Bạn không thể gọi phương thức trước khi xác định. Tuy nhiên, điều đó không có nghĩa là bạn không thể xác định myfunction trước myfunction2!Ruby có ràng buộc muộn, vì vậy cuộc gọi đến myfunction2 trong myfunction sẽ không được liên kết với myfunction2 thực tế trước khi bạn gọi myfunction. Điều đó có nghĩa là miễn là cuộc gọi đầu tiên đến myfunction được thực hiện sau khimyfunction2 được khai báo, bạn sẽ ổn.

Vì vậy, đây là ok:

def myfunction 
    myfunction2 
end 

def myfunction2 
    puts "in 2" 
end 

myfunction 

và đây không phải là:

def myfunction 
    myfunction2 
end 

myfunction 

def myfunction2 
    puts "in 2" 
end 
+2

Lưu ý không làm việc ví dụ có thể được rèn vào mã làm việc bằng cách thêm một 'BEGIN' tuyên bố: 'BEGIN {def myfunction2; đặt "trong 2"; kết thúc} '. – steenslag

+2

@steenslag Một cách tiếp cận tốt hơn nữa là thêm câu lệnh 'END':' END {myfunction} '. –

-1

Bạn có thể xác định phương thức theo bất kỳ thứ tự nào, thứ tự không quan trọng bất cứ thứ gì.

1

Ruby giải thích ngôn ngữ nên nó không phụ thuộc vào thứ tự của các chức năng, ví dụ:

[1] pry(main)> def myfunction 
[1] pry(main)* myfunction2  
[1] pry(main)* end 
=> nil 
[2] pry(main)> 
[3] pry(main)> def myfunction2 
[3] pry(main)* puts "in 2"  
[3] pry(main)* end 
=> nil 
[4] pry(main)> myfunction 
in 2 
=> nil 

Ngoài ra nếu, ví dụ, chức năng cuộc gọi chức năng không tồn tại thì ngoại lệ thời gian chạy sẽ được gọi là chỉ khi chức năng đó sẽ được gọi là, i. E .:

[5] pry(main)> def foo 
[5] pry(main)* blubry_starego_marycha 
[5] pry(main)* end 
=> nil 
[6] pry(main)> def boo 
[6] pry(main)* "bom bom bom" 
[6] pry(main)* end 
=> nil 
[7] pry(main)> boo 
=> "bom bom bom" 
[8] pry(main)> foo 
NameError: undefined local variable or method `blubry_starego_marycha' for main:Object 
from (pry):9:in `foo' 

Như bạn thấy tôi đã tuyên bố chức năng foo mà các cuộc gọi nonexisting chức năng blubry_starego_marycha và Ruby là tốt với nó, nó nâng Ngoại lệ duy nhất nếu tôi gọi foo.

7

Thời gian duy nhất vấn đề trật tự phương pháp là trong mã hoàn toàn thủ tục, và đó thường là thiển cận, đưa hai phương pháp:

def greet 
    puts "%s, Dave" % random_greeting 
end 
# If I try to use `greet` here, it'll raise a NoMethodError 
def random_greeting 
    ["Hello", "Bonjour", "Hallo"].sample 
end 
# I can use `greet` here, because `random_greeting` is now defiend 

này sẽ làm việc ok, trừ khi bạn muốn sử dụng greet trước random_greeting được định nghĩa, cách mà tất cả các mã không tầm thường giải quyết này là để bọc hành vi trong một lớp học:

class Doorman 
    def greet 
    puts "%s, Dave" % random_greeting 
    end 
    def random_greeting 
    ["Hello", "Bonjour", "Hallo"].sample 
    end 
end 
Doorman.new.greet 

một sau đó có thể chào đón khách của một người với Doorman.new.greet, bằng cách gói hành vi trong một lớp học người ta có thể mô hình ứng dụng Bett er (có thể là các đối tượng khác nhau trong mã số Hotel của bạn cung cấp các lời chào khác nhau, ví dụ) và nó cũng giữ cho không gian tên main sạch sẽ.

Đối tượng main trong Ruby đã có 114 phương thức được xác định trên nó, vì vậy tốt hơn nên đặt các phương thức của riêng bạn vào các lớp đại diện cho các tác nhân hoặc đối tượng trong mô hình dự án của bạn.

Tiếp tục với những gì bạn nói trong câu hỏi về trong khởi tạo của một lớp, điều này là hoàn toàn có thể:

class Doorman 
    def initialize 
    puts "%s, I'm a new Doorman instance" & random_greeting 
    end 
    def greet 
    "%s, Dave" % random_greeting 
    end 
    def random_greeting 
    ["Hello", "Bonjour", "Hallo"].sample 
    end 
end 

Mặc dù phương pháp random_greeting không được định nghĩa khi chúng ta viết initailize, cả lớp được xác định trước khi initialize được gọi. Một lần nữa, bằng cách gói các lớp học, điều này làm cho cuộc sống dễ dàng hơn, sạch hơn và có nghĩa là mọi thứ ở lại encapsulated.

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