2012-03-28 32 views
5

Khi trả lời một câu hỏi khác, tôi nhận ra rằng chương trình sau không hoàn toàn làm những gì tôi nghĩ.Phạm vi toàn cầu của Ruby

puts "test" 
self.puts "test" # => private method `puts' called for main:Object (NoMethodError) 

Ngoại lệ làm tôi ngạc nhiên, như tôi luôn luôn nghĩ rằng cuộc gọi phương pháp top-level sẽ được giải quyết bởi các trường hợp đối tượng main, nhưng điều này dường như không phải là trường hợp.

Ai là người nhận thực tế cuộc gọi đầu tiên và cuộc gọi được giải quyết như thế nào? Đây có phải là quy tắc đặc biệt chỉ áp dụng cho các cuộc gọi phương thức ở phạm vi cấp cao nhất không?

Trả lời

4

Đây là số good discussion nói về câu hỏi này.

Các phương pháp cấp cao nhất, được cung cấp bởi Kernel, được tự động đưa vào lớp Đối tượng. Điều này có nghĩa là các phương thức Kernel sẽ xuất hiện trong mọi thứ.

Lỗi private method 'puts' called for main:Object (NoMethodError) chỉ nêu rõ rằng các biến tồn tại nhưng được đặt ở chế độ riêng tư.

ree-1.8.7-2011.03 :001 > puts "test" 
test 
ree-1.8.7-2011.03 :004 > self.send(:puts, "hi") 
hi 

CẬP NHẬT

Không có phép thuật cho các phương pháp Kernel. Không có phạm vi nhảy hoặc bất cứ điều gì. Tôi nghĩ rằng các đường nhầm lẫn trong phạm vi sử dụng là gì khi sử dụng self. Bạn không có quyền truy cập vào các phương thức riêng tư sử dụng self.

class PutsTest 

    def success_puts 
    private_puts 
    end 

    def failed_puts 
    # trying to access a private method from self 
    self.private_puts 
    end 

    private 

    def private_puts 
    puts 'hi' 
    end 
end 

Bằng cách sử dụng tự, bạn đang thay đổi phạm vi từ cách gọi phương thức bên trong của PutsTest để gọi từ bên ngoài của PutsTest

ree-1.8.7-2011.03 :095 > test = PutsTest.new 
ree-1.8.7-2011.03 :096 > test.success_puts 
hi 
ree-1.8.7-2011.03 :097 > test.failed_puts 
NoMethodError: private method `private_puts' called for #<PutsTest:0xd62c48> 
+0

Yeah, nhưng tại sao tôi có thể gọi một phương pháp riêng nếu tôi không chỉ định 'self'? –

+0

Bởi vì đặt trên riêng của mình là phạm vi bên trong của đối tượng, trực tiếp gọi self.put có nghĩa là bạn đang cố gắng gọi phương pháp đặt phạm vi riêng tư để tự. Ill cập nhật câu trả lời của tôi với một số mã. . – mguymon

+0

Hy vọng rằng ví dụ mã giúp minh họa các giá trị so với self.puts – mguymon

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