Estoy tratando de escribir el singleton más seguro en Ruby que pueda. Soy nuevo en el lenguaje, que es tan elástico que no tengo una fuerte sensación de que mi clase Singleton tenga éxito al crear solo una instancia. Como beneficio adicional, me gustaría que el objeto solo se convierta en instancia si realmente se usa.¿Cuál es la forma correcta de escribir un patrón Singleton en Ruby?
Respuesta
# require singleton lib
require 'singleton'
class AppConfig
# mixin the singleton module
include Singleton
# do the actual app configuration
def load_config(file)
# do your work here
puts "Application configuration file was loaded from file: #{file}"
end
end
conf1 = AppConfig.instance
conf1.load_config "/home/khelll/conf.yml"
#=>Application configuration file was loaded from file: /home/khelll/conf.yml
conf2 = AppConfig.instance
puts conf1 == conf2
#=>true
# notice the following 2 lines won’t work
AppConfig.new rescue(puts $!)
#=> new method is private
# dup won’t work
conf1.dup rescue(puts $!)
#=>private method `new’ called for AppConfig:Class
#=>can’t dup instance of singleton AppConfig
Entonces, ¿qué hace ruby cuando incluye el módulo singleton dentro de su clase?
- Hace que el método
new
sea privado y, por lo tanto, no lo puede usar. - Agrega un método de clase llamado instancia que ejemplifica solo una instancia de la clase.
Así que para utilizar el módulo de rubí Singleton se necesitan dos cosas:
- requieren el lib
singleton
luego incluirlo dentro de la clase deseada. - Utilice el método
instance
para obtener la instancia que necesita.
require 'singleton'
class Klass
include Singleton
# ...
end
Véase el Ruby Standard LibrarySingleton class documention una explicación.
Si desea crear un singleton, ¿por qué molestarse en crear una clase? Simplemente cree un objeto y agregue los métodos y las variables de instancia que desee.
>> MySingleton = Object.new
=> #<Object:0x100390318>
>> MySingleton.instance_eval do
?> @count = 0
>> def next
>> @count += 1
>> end
>> end
=> nil
>> MySingleton.next
=> 1
>> MySingleton.next
=> 2
>> MySingleton.next
=> 3
Una forma más normal que la gente implementar este patrón es utilizar un Module
como el objeto Singleton (en lugar de la más genérica Object
):
>> module OtherSingleton
>> @index = -1
>> @colors = %w{ red green blue }
>> def self.change
>> @colors[(@index += 1) % @colors.size]
>> end
>> end
=> nil
>> OtherSingleton.change
=> "red"
>> OtherSingleton.change
=> "green"
>> OtherSingleton.change
=> "blue"
>> OtherSingleton.change
=> "red"
Si quería que su objeto singleton a heredar de alguna clase, solo haz que sea una instancia de esa clase. Para heredar de un mixin, simplemente use #extend
. Si desea un objeto singleton, ruby lo hace realmente fácil, y a diferencia de otros idiomas, no tiene que definirse en una clase.
Los singletons ad-hoc (mi primer ejemplo) están por todas partes, y cubren la mayoría de los casos que he encontrado. El truco del módulo normalmente cubre el resto (cuando quiero algo un poco más formal).
código Ruby debe (en mi humilde opinión) utilizar la tipificación de pato (a través de #respond_to?
) en lugar de comprobar de forma explícita la clase de un objeto, por lo que normalmente no se preocupan por la singularidad de la clase mis objetos únicos, ya que no es su clase que lo hace único, pero todo lo que agregué después.
- 1. Algunas aclaraciones sobre el patrón SyncRoot: ¿cuál es la forma correcta de usar este patrón?
- 2. ¿Cuál es la forma correcta de cargar un ListBox?
- 3. ¿Cuál es la forma correcta de redirigir?
- 4. ¿Cuál es la forma correcta de escribir en la consola de script (console.log) en IE?
- 5. ¿Cuál es la forma correcta de escribir un cliente django-piston?
- 6. ¿Cuál es la forma correcta de python para escribir métodos que solo toman un tipo particular?
- 7. ¿Cuál es la forma correcta de insertar una tubería en una expresión de patrón Java?
- 8. ¿Cuál es la forma correcta de declarar un Doctype HTML5?
- 9. ¿Cuál es la forma estándar/correcta para abrir un archivo adjunto de clip dentro de Ruby?
- 10. ¿Cuál es la forma correcta de desconectar un MediaController?
- 11. ¿Cuál es la forma correcta de verificar la existencia de objetos en Rails/Ruby?
- 12. ¿Cuál es la manera correcta de construir el patrón?
- 13. ¿Cuál es la forma correcta de escribir firmas de métodos nativos en Android NDK?
- 14. Patrón singleton en C++
- 15. phpdoc: ¿Cuál es la forma correcta de documentar una constante
- 16. ¿Cuál es la forma "correcta" de escribir Copiar/Mover/operador = trío en C++ 11?
- 17. ¿Cuál es la forma correcta de escribir una aplicación .NET que inicie sesión automáticamente en www.yahoo.com?
- 18. ¿Cuál es la forma "correcta" de iterar a través de una matriz en Ruby?
- 19. ¿Cuál es la forma correcta de acceder a las variables de clase en Ruby 1.9?
- 20. cuál es la forma correcta de separar datos en couchbase
- 21. ¿Cuál es la forma correcta de '#include file' en MVC?
- 22. ¿Cuál es la forma correcta de usar bitfields en C?
- 23. ¿Cuál es la forma correcta de manejar eventos en C++?
- 24. ¿Cuál es la forma correcta de liberar memoria en C#
- 25. ¿Cuál es la forma correcta de probar áreas en excepciones?
- 26. ¿Cuál es la forma correcta de rastrear índices en python?
- 27. ¿Cuál es la forma correcta de manejar ubicaciones geográficas en Ruby on Rails?
- 28. ¿Cuál es la forma correcta de detectar si ruby se está ejecutando en Windows?
- 29. Objective-C "mensajes": ¿cuál es la forma correcta de leerlo?
- 30. ¿Cuál es la diferencia entre un patrón de Singleton y una clase estática en Java?
+1 para señalar que no se necesita realmente singleton. Puedes implementar la intención sin copiar servilmente el patrón. –
He estado pensando mucho sobre este punto, ya que pone en tela de juicio la existencia misma del módulo Singleton en Ruby Core. La utilidad potencial de la clase w/singleton mixin me parece doble: 1) si quieres métodos de clase e instancia y 2) si tienes una inicialización complicada que quieres ejecutar perezosamente sin requerir que los métodos del módulo lo activen de alguna manera de manera explícita la primera vez que se accede a ellos ¿Alguien más tiene alguna ventaja del módulo Singleton real? – gtd