2010-01-18 15 views
7

Tengo una aplicación de rieles que carga muchos datos de algunos servicios de Java. Estoy escribiendo un módulo que me permitirá llenar algunos cuadros de selección con estos datos y estoy tratando de incluirlos adecuadamente para poder hacer referencia a ellos en mis vistas. Aquí está mi móduloruby ​​module as collection of methods

module FilterOptions 
    module Select 

    def some_select 
    return "some information" 
    end 
    end 
end 

Mi idea era incluir FilterOptions en mi application_helper, y pensé entonces podría hacer referencia a mis métodos usando Select::some_select Este no es el caso. Tengo que include FilterOptions::Select luego puedo hacer referencia al método some_select por sí mismo. No quiero eso, aunque creo que es un poco confuso para alguien que puede no saber que some_select viene de mi propio módulo.

Así que, ¿Cómo escribo métodos de un módulo que son como los métodos estáticos públicos para que pueda incluir a mi módulo principal, y la referencia de mis métodos que utilizan el espacio de nombres de sub-módulo como Select::some_select

Respuesta

11

Si define métodos módulo dentro el contexto del propio módulo, que se puede llamar sin importar:

module FilterOptions 
    module Select 
    def self.some_select 
    return "some information" 
    end 
    end 
end 

puts FilterOptions::Select.some_select 
# => "some information" 

también es posible importar un módulo, y no importe el siguiente, se refieren a ella por su nombre en su lugar:

include FilterOptions 
puts Select.some_select 
# => "some information" 
+0

bien, me siento un poco estúpido, hago esto en clases todo el tiempo consigo mismo, no sé por qué pensé que un módulo sería diferente. Por cierto, ¿cuál es la diferencia entre usar Select :: some_select y Select.some_select? – brad

+0

Esa es una buena pregunta. Cuando se trata de constantes, necesitas usar la notación :: porque no es una llamada a método, pero creo que puedes usar cualquiera de los dos métodos. – tadman

12

module_function provoca una función de módulo que se puede llamar, ya sea como un método de instancia o como una función del módulo:

#!/usr/bin/ruby1.8 

module Foo 

    def foo 
    puts "foo" 
    end 
    module_function :foo 

end 

Foo.foo  # => foo 
Foo::foo  # => foo 

include Foo 
foo   # => foo 

A veces quisiera que cada método en un módulo de ser un "módulo de funciones", pero puede resultar tedioso y repetitivo para seguir diciendo "module_function" una y otra vez. En ese caso, solo haga que su módulo se extienda:

!/usr/bin/ruby1.8 

module Foo 

    extend self 

    def foo 
    puts "foo" 
    end 

end 

Foo.foo  # => foo 
Foo::foo  # => foo 

include Foo 
foo   # => foo 
+0

hey disculpas por la respuesta tardía, gracias por los detalles, ¡ahora estoy aprendiendo metaprogramación ahora, así que lo agregaré a mi caja de herramientas! – brad

+0

De nada. Happy Hacking! –