RubyCocoa - RubyCocoa

RubyCocoa es un marco de macOS que proporciona un puente entre los lenguajes de programación Ruby y Objective-C , lo que permite al usuario manipular objetos Objective-C desde Ruby y viceversa. Hace posible escribir una aplicación Cocoa completamente en Ruby, así como escribir una aplicación que mezcle código Ruby y Objective-C. Un proyecto de Apple llamado MacRuby estaba en desarrollo para reemplazar a RubyCocoa en 2008. Posteriormente se lanzó un spin-off patentado llamado RubyMotion en 2012, disponible para iOS, macOS y Android.

Algunas aplicaciones útiles de RubyCocoa son la exploración de las características de un objeto Cocoa con irb de forma interactiva, la creación de prototipos de una aplicación Cocoa, la escritura de una aplicación Cocoa que combine las características de Ruby y Objective-C y el empaquetado de la GUI nativa de macOS para un script Ruby.

RubyCocoa es un software gratuito , publicado bajo la licencia Ruby y la LGPL .

Historia

RubyCocoa fue iniciado en 2001 por Hisakuni Fujimoto cuando implementó un módulo de extensión Ruby para envolver la función NSObject y NSClassFromString. Más tarde se integró con Project Builder (que luego se convirtió en Xcode ). En 2002, el proyecto se registró en SourceForge y el equipo de desarrollo comenzó a crecer.

En 2006, un desarrollador de Apple , Laurent Sansonetti, se unió por primera vez a la lista de confirmadores , y luego se realizó una presentación de RubyCocoa durante la WWDC . Apple declaró que RubyCocoa se incluirá y admitirá en Mac OS X v10.5 “Leopard”.

En agosto de 2008, Sansonetti confirmó que MacRuby " supuestamente reemplazará a RubyCocoa " en el futuro.

¿Cómo funciona el puente?

RubyCocoa a veces se interpreta como un conjunto de enlaces a los marcos de Cocoa, lo cual es falso. RubyCocoa es un puente real entre los lenguajes de programación Objective-C y Ruby.

Importación de clases perezosas

RubyCocoa importará las clases de Objective-C al mundo de Ruby a pedido. Por ejemplo, cuando acceda OSX::NSTableViewpor primera vez en su código, RubyCocoa recuperará toda la información necesaria con respecto a esta clase del tiempo de ejecución de Objective-C y creará una clase Ruby del mismo nombre que actuará como un proxy. También importará de la misma forma todas las clases heredadas.

Reenvío de mensajes

Como se indicó anteriormente, RubyCocoa crea objetos proxy especiales. Cada vez que envíe un mensaje de Ruby a un objeto proxy, RubyCocoa intentará reenviarlo a la instancia incrustada de Objective-C, traduciendo el nombre del mensaje a un selector de Objective-C y pidiendo al tiempo de ejecución de Objective-C que lo reenvíe.

Si se genera una excepción desde el mundo Objective-C, RubyCocoa la convertirá en una excepción de Ruby y se la enviará.

RubyCocoa utiliza el libffi biblioteca para llamar a los métodos de Objective-C implementaciones.

Anulación automática del método

RubyCocoa hace que sea fácil anular un método Objective-C de Ruby, ya sea en una subclase o directamente a la clase (como lo haría en Objective-C usando una categoría).

Una vez que se inserta su método, RubyCocoa recuperará la firma del método Objective-C existente e inyectará una nueva en el tiempo de ejecución de Objective-C, de la misma firma, pero que ahora apunta a su código.

Para lograr esto, utiliza el RubyCocoa libffi biblioteca para crear dinámicamente un cierre que llamará al método de Ruby, y apenas pasa un puntero a ese nuevo cierre al tiempo de ejecución de Objective-C.

Accediendo a los bits C

Debido a la naturaleza del lenguaje Objective-C, puede usar libremente C desde el código Objective-C. Para unir las partes C relevantes de un marco de Objective-C, como estructuras, funciones, enumeraciones, constantes y más en C, RubyCocoa se basa en el proyecto BridgeSupport .

RubyCocoa interpretará en tiempo de ejecución los archivos BridgeSupport (utilizando el muy rápido xmlTextReader de libXML 2) y, en consecuencia, manejará su contenido. Por ejemplo, construirá las clases de proxy Ruby para las estructuras C y también creará las funciones.

Tenga en cuenta que las operaciones costosas, como la localización de los símbolos, se realizan a pedido y, obviamente, solo una vez.

Formatear cadenas

RubyCocoa puede detectar API que utilizan cadenas de formato, como NSLog o NSString.stringWithFormat, y convertir adecuadamente los argumentos de la variable a los tipos especificados en la cadena de formato.

Punteros de función

RubyCocoa le permite pasar Procobjetos Ruby como argumentos de puntero de función. Luego usará la biblioteca libffi para crear dinámicamente un cierre y pasarlo a la función / método subyacente.

Creación de aplicaciones Cocoa escritas en Ruby

La instalación de RubyCocoa también instala automáticamente las plantillas Xcode correspondientes . Esto permite a los desarrolladores seleccionar "Aplicación Cocoa-Ruby" como el tipo de proyecto Xcode y Xcode generará todos los archivos necesarios para ellos.

Cómo llamar a métodos Objective-C desde Ruby

Para invocar un método Objective-C, reemplace cada dos puntos en el nombre del método, excepto el último, con un guión bajo. Así, por ejemplo, el método de instancia NSWindow se initWithContentRect:styleMask:backing:defer:convierte en initWithContentRect_styleMask_backing_defer.

Todas las clases y funciones de Cocoa pertenecen al OSXmódulo, por ejemplo, el código Objective-C:

[[NSWindow alloc] initWithContentRect:frame
                            styleMask:NSTitledWindowMask
                              backing:NSBackingStoreBuffered
                                defer:NO]

se convertirá:

OSX::NSWindow.alloc.initWithContentRect_styleMask_backing_defer(frame,
  OSX::NSTitledWindowMask,
  OSX::NSBackingStoreBuffered,
  false)

Como puede ver, esto disminuye la legibilidad del código al hacer que los nombres de los parámetros de Objective-C sean inútiles. Por lo tanto, hay otra forma conveniente de escribir las llamadas al objc_sendmétodo : el método, que acepta símbolos Ruby como nombres de parámetros. Por ejemplo, el código anterior también se puede escribir como:

OSX::NSWindow.alloc.objc_send(:initWithContentRect, frame,
  :styleMask, OSX::NSTitledWindowMask,
  :backing, OSX::NSBackingStoreBuffered,
  :defer, false)

Ventajas de RubyCocoa

  • Como Ruby es un lenguaje interpretado, no es necesario volver a compilar la aplicación con frecuencia durante el desarrollo.
  • Algunas de las características ricas de Ruby, como la compatibilidad con expresiones regulares incorporadas, hacen que escribir el código sea más rápido y también hacen que RubyCocoa sea una herramienta ideal para la creación de prototipos.

Desventajas

  • Ignorando la velocidad del intérprete de Ruby, las aplicaciones RubyCocoa siempre serán más lentas que las aplicaciones Objective-C / Cocoa debido a la sobrecarga adicional de conversión de objetos.
  • Debido a que Ruby no es seguro para subprocesos, no es posible enviar varios subprocesos nativos para ejecutar el código RubyCocoa. Sin embargo, se pueden usar los hilos emulados de Ruby.

enlaces externos