Introduction à MacRuby

Publié le 9 novembre 2010 par Nicolas Cavigneaux | autre

Cet article est publié sous licence CC BY-NC-SA

MacRuby, qu’est ce que c’est ?

MacRuby est une implémentation alternative de Ruby 1.9 basée sur le coeur des technologies Mac OS X telles que les librairies d’Objective-C, son garbage collector ou encore Cocoa. Le but premier de MacRuby est de vous permettre de créer des applications Mac OS X natives en utilisant Ruby sans sacrifier les performances. MacRuby nous apporte le meilleur des deux mondes :

  • la puissance et la flexibilité de Ruby combinée avec la richesse de l’environnement Cocoa
  • la robustesse d’Objective-C

Pourquoi avoir développé MacRuby ?

Le projet MacRuby a été démarré pour palier à des problèmes inhérents à RubyCocoa. En s’attelant à résoudre ses problèmes, MacRuby a également résolu de nombreux autres soucis directement liés à Ruby 1.8. MacRuby est donc devenu une alternative incontestable pour ceux qui veulent écrire une application flexible et performante tout en gardant la simplicité et la beauté de Ruby. En voici quelques raisons :

  • performance : basé sur Ruby 1.9 et utilise donc YARV ce qui améliore considérablement les temps d’exécution
  • gestion de threads : passage des threads verts (émulés) aux threads natif POSIX
  • garbage collection : le garbage collector inclut dans Ruby est réputé pour être lent et bloquant lorsqu’il se déclenche, MacRuby profite d’Objective-C et de son garbage collector plutôt que de ré-inventer la roue
  • accès au framework Mac OS X : accès à toutes les classes Objective-C et Cocoa de manière native et transparente, pas d’utilisation de proxy

Tour d’horizon

MacRuby est un mélange unique entre Ruby 1.9 et Objective-C. Le but de MacRuby est d’être 100% compatible avec Ruby 1.9 en terme de syntaxe et de comportement. A l’heure actuelle, dans sa version 0.7, MacRuby passe avec succès 90% des RubySpecs. Bien que les deux interpréteurs se comportent de la même façon, le fonctionnement en interne diverge sur plusieurs points. Il est également à noter qu’en l’état, rien ne garantit que du code fonctionnant sous l’interpréteur MRI fonctionnera également dans MacRuby. C’est le cas notamment pour Ruby on Rails qui n’est pas encore supporté mais qui devrait l’être d’ici peu.

Voyons maintenant les aspects qui différencient MacRuby et l’interpréteur standard Ruby 1.9 ‘MRI’.

Les classes et les objets

Les classes Ruby dans MacRuby sont en fait des classes Objective-C. Ceci est vrai à quelques détails près, des limitations sémantiques dans Objective-C font qu’il est à l’heure actuelle toujours nécessaire de passer par des ajouts en Ruby pur pour certaines choses comme par exemple ajouter des variables d’instance à une classe lors de l’exécution.

Chaque méthode définie dans une classe Ruby est enregistrée comme étant une méthode d’une classe Objective-C. Les méthodes des classes Objective-C sont elle également disponibles de manière transparente depuis Ruby.

Toutes les classes Ruby héritent de NSObject qui est la classe parent de la majorité des objet dans le monde Cocoa. Vous aurez donc, par défaut, l’ensemble de vos objets Ruby qui répondront aux nombreuses méthodes définies dans NSObject.

Les classes Objective-C sont elles importées sur demande dans Ruby.

On peut donc utiliser des classes Ruby, Objective-C, séparément ou ensemble de manière tout à fait transparente comme si tout était du Ruby pur.

Classes primitives

L’ensemble des classes primitives (String, Array, and Hash) ont été ré-implémentées sur la base de leur équivalent Cocoa (NSString, NSArray, and NSDictionary).

Pour être plus clair, String n’est plus une classe mais un pointeur vers NSMutableString. Toutes les chaînes dans MacRuby sont en fait des chaînes Cocoa natives et peuvent donc être transmisse sans aucune modification à une API C ou Objective-C APIs qui attend une chaîne Cocoa.

Vous pouvez donc utiliser n’importe quelle méthode des classes de base Ruby sur des objets Cocoa. Bien évidemment vous avez également la possibilité d’utiliser les méthodes des classes Cocoa.

Chargement des Frameworks

MacRuby apporte une nouvelle méthode Kernel#framework qui permet de charger un framework C ou Objective-C.

Cette méthode va détecter les fichiers BridgeSupport dans le framework et ses dépendances, les analyser et construire l’API Ruby correspondante.

Arguments nommés

MacRuby utilise un syntaxe spéciale pour appeler et définir les méthodes Objective-C utilisant les arguments nommés. Cette syntaxe est basée sur le même principe que la définition de Hash : clé:valeur ou :clé => valeur.

Garbage Collection

MacRuby utilise le garbage collector introduit récemment dans Objective-C plutôt que d’utiliser le GC inclus dans Ruby.

La collections des objets périmés se fait dans un thread séparé ce qui a le gros avantage de ne pas interrompre l’exécution du programme pendant la collecte. La collecte est aussi de ce fait bien plus rapide qu’avant.

Quelques exemples concrets

Chargez un framework

>> framework 'Cocoa'
=> true

Accès aux classes

  >> framework 'Cocoa'
  => true

  >> NSSound.ancestors
  => [NSSound, Object, NSObject, Kernel]

  >> Regexp.ancestors
  => [Regexp, Object, NSObject, Kernel]

  >> s = "foo"
  => "foo"
  >> s.class
  => String
  >> s.class.ancestors
  => [String, NSMutableString, NSString, Comparable, NSObject, Kernel]

  # Méthode Ruby
  >> s.respond_to?(:upcase)
  => true
  # Méthode Objective-C
  >> s.respondsToSelector(:upcase)
  => true
  # Méthode Ruby
  >> s.upcase
  => "FOO"
  # Méthode Objective-C
  >> s.uppercaseString
  => "FOO"

Utiliser Cocoa

Nous avons donc accès à toute l’API fournie par Cocoa, il est donc très facile de créer une fenêtre, lire un son, contrôler iTunes, utiliser une voix de synthèse pour lire un texte et bien d’autres choses encore :

  # Lire un son système
  >> NSSound.soundNamed('Basso').play
  => true

  # Contrôler Itunes
  framework 'Foundation'
  framework 'ScriptingBridge'

  itunes = SBApplication.applicationWithBundleIdentifier("com.apple.itunes")
  load_bridge_support_file 'iTunes.bridgesupport'
  itunes.soundVolume = 30
  itunes.currentTrack.name
  itunes.soundVolume = 100
  itunes.stop

  # Détecter la langue d'un texte
  framework 'Foundation'
  class String
    def language
      CFStringTokenizerCopyBestStringLanguage(self, CFRangeMake(0, self.size))
    end
  end

  >> puts "Bonne année!".language
  => "fr"
  >> puts "Happy new year!".language
  => "en"

  # Voix synthétisée
  framework 'AppKit'
  voice_type = "com.apple.speech.synthesis.voice.GoodNews"
  voice = NSSpeechSynthesizer.alloc.initWithVoice(voice_type)
  voice.startSpeakingString("Bonjour Synbioz !")

Installation

Il est maintenant temps de se mettre à écrire des application en MacRuby !

Mac OS X

Assurez vous d’utiliser Snow Leopard si vous voulez utiliser la dernière version de MacRuby (0.7).

MacRuby

Rendez-vous sur le site de MacRuby, téléchargez l’installeur et exécutez le. Et voilà, vous avez maintenant accès à macruby, macirb, macrake, macri, macrdoc et macgem.

Conclusion

Nous avons donc vu avec cette rapide introduction à MacRuby, que nous avons accès à un moyen fun, rapide et sexy de créer des applications Mac natives via notre langage préféré. Vous avez à disposition un nombre incroyable d’outils pour créer une application native très riche. Les possibilités n’ont pour limite que l’imagination. Dans les prochains articles nous essayerons de découvrir des fonctionnalités plus avancées.

L’équipe Synbioz.

Libres d’être ensemble.