He escrito algunas clases que contienen un conjunto de configuraciones y acciones y cada clase está en su propio espacio de nombres (módulo). Tengo una constante regex en cada espacio de nombres que quiero usar para que coincida con una entrada que determinará qué clase instanciaré (la matriz se usa para establecer el orden de prioridad). Quiero instanciar la clase <namespace>::PrintSomeWorld pero parece que no puedo obtener directamente el espacio de nombres de la expresión regular coincidente.

Pregunta: ¿Hay un comando para obtener el espacio de nombres de un objeto? El siguiente código muestra mi solución actual donde paso el nombre del módulo como parte del objeto de datos MY_REGEX. Sin embargo, sería más limpio simplemente conocer el espacio de nombres del objeto coincidente.

module MyHelloTest
  MY_REGEX = {mname: name, mregex: /test/}
  class PrintSomeWorld
    def initialize
      p "hello world!"
    end
  end
end

module MyGoodbyeTest
  MY_REGEX = {mname: name, mregex: /goodbye/}
  class PrintSomeWorld
    def initialize
      p "goodbye world!"
    end
  end
end

mytests = [MyHelloTest::MY_REGEX, MyGoodbyeTest::MY_REGEX]
found_regex = mytests.find {|f| f[:mregex].match("this is a goodbye")}
Object.const_get(found_regex[:mname])::PrintSomeWorld.new
0
Greg Ruhl 8 sep. 2018 a las 01:15

3 respuestas

La mejor respuesta

Si bien es posible extraer este tipo de información de las expresiones regulares, ese enfoque sufre de microgestión. El código de llamada sabe demasiado sobre la estructura de los módulos y tiene que hacer demasiado trabajo innecesario. Agregar solo el bit más pequeño de OOP hace que el problema desaparezca.

module MyHelloTest
  MY_REGEX = /test/

  def self.match(str)
    MY_REGEX.match(str)
  end

  def self.print
    PrintSomeWorld.new
  end

  class PrintSomeWorld
    def initialize
      p "hello world!"
    end
  end
end

module MyGoodbyeTest
  MY_REGEX = /goodbye/

  def self.match(str)
    MY_REGEX.match(str)
  end

  def self.print
    PrintSomeWorld.new
  end

  class PrintSomeWorld
    def initialize
      p "goodbye world!"
    end
  end
end

mytests = [MyHelloTest, MyGoodbyeTest]
found_module = mytests.find {|f| f.match("this is a goodbye")}
found_module.print
# >> "goodbye world!"
2
Sergio Tulentsev 7 sep. 2018 a las 23:08

No estoy seguro si realmente entendí tu pregunta, pero si ya tienes el objeto y tiene un módulo, como lo describiste, puedes usar:

your_object.class.parent
0
sad parrot 7 sep. 2018 a las 22:52

Puede usar Module :: nesting.

module MyHelloTest
  class PrintSomeWorld
    Module.nesting
  end
end
  #=> [MyHelloTest::PrintSomeWorld, MyHelloTest]
0
Cary Swoveland 7 sep. 2018 a las 22:43