Archive for the ‘Ruby’ Category

Programming Cocoa With MacRuby: Part One

In this series of articles, I will work through the Pragmatic Programmer book Programming Cocoa with Ruby by Brian Marick, porting the examples to MacRuby.

Examples from Chapter 2

The first few examples are almost identical. require 'osx/cocoa' becomes framework 'cocoa'. MacRuby lets us use the familiar SomeObject.new instead of SomeObject.alloc.init, and there is no need to explicitly inherit from NSObject, since NSObject replaces Object in the standard class hierarchy:

irb(main):011:0> class Foo;end;Foo.ancestors
=> [Foo, NSObject, Kernel]
irb(main):012:0>

most-basic-app.rb

#!/usr/bin/env macruby
framework 'cocoa'
NSApplication.sharedApplication
NSApp.run

no-ui.rb

#!/usr/bin/env macruby
framework 'cocoa'

class AppDelegate
  def applicationDidFinishLaunching(aNotification)
    puts "#{aNotification.name} makes me say: Hello, world"
  end
end

our_object = AppDelegate.new
NSApplication.sharedApplication
NSApp.setDelegate(our_object)
NSApp.run

Pages: 1 2 3

“Ruby Rocks” ported to MacRuby

MacRuby logoWhen I first started playing around with writing Cocoa apps using Ruby, I was using RubyCocoa. I did the Ruby Rocks tutorial and was pretty impressed by how easy it was to write graphics apps using Ruby and Cocoa. I quickly discovered MacRuby and decided to use it going forward. The first thing I did was to port my finished Ruby Rocks to MacRuby, so I’m posting in as a MacRuby sample.

Possibly at some point I will write up the conversion to MacRuby as a tutorial. Anywhere, here it is. You can see that I kept playing for a while after finishing the tutorial…

Download

A Dirt-Simple Hierarchical, Configurable Logger for Ruby

log4r is currently broken in MacRuby, and I was desperate for a log4j-ish logger in the MacRuby app I’m working on, so I put together this very basic hierarchical logger based on the standard ruby logger. I’m posting it in case anybody else has the same problem with MacRuby, or wants something that is a little simpler than log4j to configure.

require 'logger'
require 'forwardable'

class LogGroup < Logger
  extend Forwardable

  def_delegators :@child_loggers, :[]=, :has_key?

  attr_accessor :child_loggers

  def initialize(logdev, shift_age = 0, shift_size = 1048576)
    super
    @child_loggers = {}
  end

  def self.init_with_config(config)
    logdev = config['device'] || STDOUT
    shift_age = config['shift_age'] || 0
    shift_size = config['shift_size'] || 1048576
    root = LogGroup.new(logdev, shift_age, shift_size).with_name('root')

    config['loggers'].each do |name, level|
      name_parts = name.split('.')
      log_group = root
      name_parts.each do |name_part|
        unless log_group.has_key?(name_part)
          log_group[name_part] = LogGroup.new(logdev, shift_age, shift_size).with_name("#{log_group.progname}.#{name_part}")
        end
        log_group = log_group[name_part]
      end
      log_group.level =  Logger::Severity.const_get(level.upcase.to_sym)
    end
    root
  end

  def with_name(name)
    @progname = name
    self
  end

  def inspect
    "#{@progname}(#{@level}) -- #{@child_loggers.inspect}"
  end

  def [](dotpath)
    logger = self
    name_parts = dotpath.split('.')
    while (name = name_parts.shift) && logger.has_key?(name)
      logger = logger.child_loggers[name]
    end
    logger
  end
end

To use it, create a config file like so:

device: logfile
loggers:
  cocoa.document:           debug
  cocoa.codeview:           warn
  cocoa.diagramview:        debug

And use it like this:

require "yaml"
require "log_group"
log_cfg = YAML.load_file("log_config.yaml")

$log = LogGroup.init_with_config(log_cfg)

$log['cocoa'].debug("this is a debug message from cocoa")
$log['cocoa.codeview'].debug("this is a debug message from cocoa.codeview")
$log['cocoa.diagramview'].debug("this is a debug message from cocoa.diagramview")

This will output to logfile:

  # Logfile created on 2009-12-19 02:42:05 -0800 by logger.rb/20321
  D, [2009-12-19T02:42:05.549777 #49807] DEBUG -- root.cocoa: this is a debug message from cocoa
  D, [2009-12-19T02:42:05.586840 #49807] DEBUG -- root.cocoa.diagramview: this is a debug message from cocoa.diagramview
Return top

Web Application Developer

LastObelus hacks on web applications for enterprise. Usually in Rails or Merb these days, but he has worked WebObjects, J2EE, and various PHP frameworks.