2012-04-06 17 views
7

test_module.rbcủa Ruby module_function, phương pháp riêng gọi module, viện dẫn trong phương pháp lớp phong cách trên mô-đun cho thấy lỗi

module MyModule 
    def module_func_a 
     puts "module_func_a invoked" 
     private_b 
    end 

    module_function :module_func_a 

    private 
    def private_b 
     puts "private_b invoked" 
    end 
    end 

    class MyClass 
    include MyModule 
    def test_module 
     module_func_a 
    end 
    end 

Gọi chức năng mô-đun từ lớp

c = MyClass.new 
    c.test_module 

Output 1:

$ ruby test_module.rb 
module_func_a invoked 
private_b invoked 

Gọi chức năng mô-đun trên mô-đun trong phương pháp phong cách lớp

ma = MyModule.module_func_a 

Output 2:

module_func_a invoked 
test_module.rb:5:in `module_func_a': undefined local variable or method `private_b' for MyModule:Module (NameError) 
from test_module.rb:31 

Như có thể thấy từ đầu ra 1 và Output 2 khi bao gồm các module trong một lớp, không có vấn đề xảy ra khi phương thức riêng của một mô-đun được gọi từ một hàm mô-đun trong khi trong trường hợp khi trực tiếp gọi hàm mô-đun trên mô đun trong c Kiểu phương thức lass phương thức riêng của module, được gọi từ hàm module, không tìm thấy.

Ai đó có thể làm cho tôi hiểu lý do đằng sau hành vi trên và có gọi chức năng mô-đun (mà lần lượt gọi phương thức riêng của mô-đun) trên mô-đun trong kiểu phương thức lớp không? Nếu có thể, thì những điều chỉnh nào được yêu cầu trong mã của tôi để làm như vậy?

Trả lời

6

Nó hoạt động khi bạn bao gồm các mô-đun trong một lớp học, bởi vì sau đó tất cả các phương thức của mô-đun được bao gồm trong lớp đó (các self trong module_func_a điểm để MyClass, mà còn có phương pháp private_b).

Trong trường hợp khác, tự trỏ đến MyModule, không có phương thức private_b. Nếu bạn muốn nó hoạt động theo cả hai cách, bạn phải khai báo private_b làm phương thức mô-đun, hoặc chỉ cần thêm dòng extend self đến MyModule, để tất cả các phương thức của nó sẽ trở thành phương thức mô-đun.

+0

Thanks.This works.I đã thử mở rộng self to MyModule và nó đang hoạt động. Tuy nhiên, dường như trong trường hợp này riêng tư có vẻ thừa và không có tác dụng. Có phải trong trường hợp như đã đề cập, chúng tôi không thể tạo các phương thức riêng tư? Ví dụ: tôi cần tạo một phương thức tiện ích chỉ nên sử dụng bởi mô-đun hoặc chức năng mô-đun và không được tiếp xúc với người dùng của mô-đun –

+0

Bạn không thể và đó là lý do tôi thích sử dụng ủy quyền. – psyho

+2

@pysho - Bạn có thể vui lòng cung cấp cho tôi một ví dụ hoặc cung cấp cho tôi một liên kết cung cấp chi tiết về cách sử dụng ủy quyền mà bạn đã đề cập không? –

3

module_function sao chép số module_func_a của bạn vào metaclass chứ không phải phụ thuộc của nó.

Vì vậy, khi gọi module_func_a từ một đối tượng, bạn sẽ có được phương thức khác private_b. Nhưng gọi nó trên mô-đun chính nó không thành công vì private_b không phải là một chức năng mô-đun.

Bạn cũng nên sử dụng module_function cho private_b và nó sẽ hoạt động.

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