2012-04-06 12 views
7

test_module.rbRuby module_function, prywatna metoda powołując modułu, wywoływana w metodzie klasy stylu na module pokazuje error

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 

Wywoływanie funkcji modułu z klasy

c = MyClass.new 
    c.test_module 

Wyjście 1:

$ ruby test_module.rb 
module_func_a invoked 
private_b invoked 

Wywoływanie funkcji modułu na moduł w metodzie klasy stylu

ma = MyModule.module_func_a 

Wyjście 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 

Jak widać z wyjścia 1 i wyjścia 2 gdy w tym module w klasa, żaden problem nie występuje, gdy metoda prywatna modułu jest wywoływana z funkcji modułu , podczas gdy w przypadku bezpośredniego wywołania funkcji modułu w module c Metoda metody lass nie została znaleziona metoda prywatna modułu, wywołana z funkcji modułu.

Czy ktokolwiek może mi zrozumieć przyczynę powyższego zachowania i czy wywołanie funkcji modułu (która z kolei wywołuje metodę prywatną modułu) w stylu modułu w klasie jest możliwe, czy nie? Jeśli to możliwe, to jakie poprawki są wymagane w moim kodzie, aby zrobić to samo?

Odpowiedz

6

To działa, kiedy to moduł w klasie, bo wtedy wszystko metod modułu uzyskać zawarte w tej klasie (w self w module_func_a punktów do MyClass, który ma również metodę private_b).

W pozostałych punktach sytuacja własny do MyModule, który nie ma sposobu private_b. Jeśli chcesz go do pracy w obu kierunkach, to trzeba albo zadeklarować private_b jako metoda modułu, jak również, czy po prostu dodać linię extend self do MyModule, tak że wszystkich jego metody staną metody ładowania.

+0

Thanks.This works.I próbował przedłużyć do siebie mymodule i jest working.However wydaje się, że w tym przypadku wydaje się zbędny prywatne i nie ma effect.So jest to, że w przypadkach takich jak te wymienione nie możemy tworzyć metody prywatne? Na przykład powiedzieć, że trzeba utworzyć metodę narzędzie, które powinny być używane tylko przez moduł instancji lub moduł funkcji i nie powinien być narażony na użytkowników modułu –

+0

nie może i dlatego wolę używać delegację. – psyho

+2

@pysho - Czy możesz podać mi przykład lub podać mi link, który zawiera szczegółowe informacje na temat korzystania z delegacji, o której wspomniałeś? –

3

module_function kopiuje twój module_func_a do metaclass, ale nie jego zależności.

Tak więc wywołując module_func_a z obiektu, otrzymujesz inną metodę private_b. Ale wywołanie go na samym module nie powiedzie się, ponieważ private_b nie jest funkcją modułu.

Należy użyć module_function dla private_b zbyt i to powinno działać.