TextMate bundles for Merb

Posted by Dr Nic on May 12, 2008

If you are using TextMate (OS X) or E Text Editor (Windows) then you’ll be dead keen to know there is a TextMate bundle for Merb, and another one for Datamapper.

[This is cross-posted on the new Merbunity community site for Merb]

Currently, you can access the bundles via git:

cd "~/Library/Application Support/TextMate/Bundles"
git clone git://github.com/drnic/datamapper-tmbundle.git Datamapper.tmbundle
git clone git://github.com/drnic/merb-tmbundle.git Merb.tmbundle

Now “Reload Bundles” or restart TextMate.

You can now select from three Merb syntax/scopes. Press Shift+Alt+Cmd+M to see the options (below)

Merb TextMate bundle - select ORM

  • If you select Merb (Datamapper) you will have access to the Merb bundle AND the Datamapper bundle.
  • If you select Merb (ActiveRecord) you have access to the Merb bundle AND the Ruby on Rails bundle.
  • If you select Merb (Sequel) then nothing special happens as there isn’t a Sequel bundle yet. Want to create one?

Currently there is no separation in the Rails bundle for ActiveRecord and non-ActiveRecord snippets and commands, so if you use Merb (ActiveRecord) there will be some snippets + commands that you don’t want from Rails. In future, there may be more separation to help the Merb bundle. Also, TextMate 2 may help this cause.

As always, to learn what snippets are available at any given cursor position, use Ctrl+Cmd+T.

If you have new snippets for any of the bundles, I suggest forking the git repositories, pushing up the changes to github and sending Pull Requests to me (drnic).

Sponsored by Engine Yard

The initial development of this bundle was sponsored by Engine Yard because they care.

Rails bundle

There is also the hughly popular Ruby on Rails bundle for TextMate that you can use. Download from http://railsbundle.com/ or via github.

If you want to learn everything about the new Ruby on Rails bundle for TextMate and daily life with TextMate (short cuts, editing bundles) then I highly recommend the new TextMate for Rails 2 Peepcode:

TextMate for Rails 2

This recommendation comes from inside information on the quality of the Peepcode… it was written by me, and incorporates the vocal skills of the operatic Geoffrey Grosenbach.

The explicit Ruby metaclass you know you always wanted

Posted by Dr Nic on April 03, 2008

When you define a “static” or “class” method on a Ruby class, it actually stores the method on that class’s metaclass/singleton class/eigenclass.

_why’s metaid gem gives you a metaclass method to explicit access this object:

require 'metaid'
class Person
  def self.oldest
    # find oldest person
  end
end
Person.methods.grep(/oldest/) # => ['oldest']
Person.metaclass.instance_methods.grep(/oldest/) # => ['oldest']

So now here’s a new, fun way to access the metaclass of a class, look for a constant suffixed with ‘Metaclass’. For the Person class, look for PersonMetaclass. Yep, we can have explicit metaclass constants. Or try PersonClass or PersonEigen or PersonEigenclass. No one can agree on what they are called, so I made them all work.

$ gem install magic_metaclass
$ irb

In irb try:

require 'rubygems'
require 'magic_metaclass'
class Person; end
Person
# => Person
PersonMetaclass
# => #<Class:Person>
PersonClass
# => #<Class:Person>
PersonEigenclass
# => #<Class:Person>
PersonEigen
# => #<Class:Person>

Neat.

Finally, the example from above:

class Person
  def self.oldest
    # find oldest person
  end
end
PersonMetaclass.instance_methods.grep(/oldest/) # => ['oldest']

I wrote this gem with no known use cases. If you find any, let me know.

Writing C extensions in RubyGems using newgem generators (plus a free TextMate bundle)

Posted by Dr Nic on April 01, 2008

Already know C extensions in RubyGems? Cool - then just run the following cmds and see what can be generated for you; plus check out the TextMate bundle at the bottom.

sudo gem install newgem
newgem pickaxe
cd pickaxe
script/generate extconf my_test
rake test

For everyone else…

Its 15000km from Brisbane AU to Prague CZ where Euruko2008 - the European Ruby Conf - was held. I came ready to talk, to met lots of cool multi-lingual Rubyists, and to learn. Ooh, I learnt something alright.

Tim Becker was introducing Native C Extensions for Ruby, and fortunately he said “now, everyone, follow along with this example”. I’d never done native C extensions, but I’d received lots of requests from RubyGem developers on how to do it. I had no idea.

So I was typing in everything Tim told me to type in. When Tim changed slides too quickly, I may have yelled at him to slow down. Perhaps I was the only one doing his tutorial out of 300 people, but I didn’t care. This was gold.

After he finished his session, I dragged him off into the corridor with Jonas Pfenniger (zimbatm), and the three of us mapped out a generic layout for how native C extensions work within RubyGems. I didn’t know any of this, but Tim and Jonas did, and we probably looked silly sitting at a small table in the middle of the narrow corridor.

But at the end, we had a working RubyGem with native C extensions that were built: when the tests were executed via rake, and when the gem was installed. The next day I figured out how to get the C extension built via autotest.

Thanks to Tim and Jonas I was able to then write a extconf generator for RubyGems so that its super-super easy to get started writing native C extensions within RubyGems.

Tutorial

This tutorial is for *nix, as I’m still investigating win32 extensions, and jruby + .net/ironruby extensions. So when I figure that out - hopefully with the help of other people currently at RubyFools conferences, I’ll get back to you.

The code comes from the Pickaxe book - p264, and we’ll insert it into a new RubyGem using newgem (version 0.20.1+):

sudo gem install newgem
newgem pickaxe
cd pickaxe
script/generate extconf my_test

Create a test for a class MyTest that doesn’t exist yet:

# test/test_my_test_extn.rb
require "test/unit"
require 'pickaxe'

class TestMyTestExtn < Test::Unit::TestCase
  def test_working
    t = MyTest.new
    assert_equal(Object, MyTest.superclass)
    assert_equal(MyTest, t.class)
    t.add(1)
    t.add(2)
    assert_equal([1,2], t.instance_eval(”@arr”))
  end
end

Run rake to build the C extension and run the tests. You can also run autottest and it will automatically build the C extension before running the tests.

To create the MyTest class, using the code from p262 of the Pickaxe book:

#include "ruby.h"
static int id_push;

static VALUE t_init(VALUE self)
{
  VALUE arr;
  arr = rb_ary_new();
  rb_iv_set(self, "@arr", arr);
  return self;
}

static VALUE t_add(VALUE self, VALUE obj)
{
  VALUE arr;
  arr = rb_iv_get(self, "@arr");
  rb_funcall(arr, id_push, 1, obj);
  return arr;
}

VALUE cTest;
void Init_my_test() {
  cTest = rb_define_class("MyTest", rb_cObject);
  rb_define_method(cTest, "initialize", t_init, 0);
  rb_define_method(cTest, "add", t_add, 1);
  id_push = rb_intern("push");
}

To lib/pickaxe.rb:

require "my_test.so"
# or require 'my_test' if its unique

The last line will import the generated shared library. If the RubyGem is tested or installed on Windows, then the .dll file will be automatically loaded instead. The “.so” notation is merely a placeholder to explicitly specify the shared C-extension, rather than any Ruby library of the same name.

Now run tests (rake), the C extension will be rebuilt and the tests will pass.

Build and install RubyGem

rake manifest:refresh
rake install_gem
irb -rubygems -rpickaxe
> a = MyTest.new
> a.add 3

You have successfully created a C-extension within RubyGems, using TDD.

TextMate bundle for Ruby C extensions

I’ve started a TextMate bundle to give syntax highlighting + some simple snippets for developing the C files for Ruby extensions.

To install:

cd ~/Library/Application Support/TextMate/Bundles
git clone git://github.com/drnic/ruby-c-extensions-tmbundle.git "Ruby C Extensions.tmbundle"

or 

wget http://github.com/drnic/ruby-c-extensions-tmbundle/tarball/master
tar xfv drnic-ruby-c-extensions-tmbundle-master.tar.gz
mv drnic-ruby-c-extensions-tmbundle-master "Ruby C Extensions.tmbundle"

Then restart TextMate or “Reload Bundles”.

You can clone/fork the source via http://github.com/drnic/ruby-c-extensions-tmbundle/tree/master

Rails 2.0 TextMate bundle - Tasty Tidbit - respond_to and view navigation

Posted by Dr Nic on February 27, 2008

The new release of the Rails TextMate bundle is coming soon. Its guaranteed to be shiny, sparkly and will fit in with any home or office decor. More importantly, it will be upgraded for Rails 2.0.

Today is the first Tasty Tidbit - a demonstration of one of the snazzy new features coming to your Macintosh soon.

In this Tasty Tidbit, we look at respond_to and the ability to create and navigate to view templates based on the selected format block, such as wants.js -> .js.rjs.

Cannot see the embedded video? Want the Hi-Def version? Download the video (5 Mb).

Contribute to the Bundle

To clone the git repository and start sharing your own personal goodness, see previous article.

One-stop JavaScript Unit Testing for Rails 2.0

Posted by Dr Nic on February 19, 2008

Previously, I mentioned a multi-step/multi-project solution to doing JavaScript Unit Testing for Rails, including an autotest script to make TDD life easier for the autotest-addicted.

It was too many steps, too many different projects, and too much dependence on prototypejs. So let’s fix this via the spanky new newjs (introduced here):

Instead of several steps, there is now two steps:

cd myrailsapp                # rails 2.0 app
sudo gem install newjs       # v1.3.1+
script/generate javascript_test application
    create  vendor/plugins/javascript_unittest/lib
    create  vendor/plugins/javascript_unittest/tasks
    create  test/javascript/assets/jsunittest.js
    create  test/javascript/assets/unittest.css
    create  config/javascript_test_autotest.yml.sample
    create  vendor/plugins/javascript_unittest/lib/jstest.rb
    create  vendor/plugins/javascript_unittest/tasks/runner.rake
    create  vendor/plugins/javascript_unittest/tasks/autotest.rake
    create  vendor/plugins/javascript_unittest/README
    create  test/javascript/application_test.html
    create  script/rstakeout
    create  script/js_autotest

It installs all assets, gives you a rake test:javascripts task, gives you script/js_autotest, and finally (and most importantly), creates the application_test.html test stub.

As always, you can also run a single test file by loading it into a browser.

Prototype independence

Previously, the test suite - unittest.js - had a dependency on prototypejs. This was wonderful if you’re developing in prototypejs, but could cause some grief if you weren’t.

newjs now comes packed with an identical test suite - jsunittest - but it is built without a dependency on prototypejs.

Merb et al support

I wrote a rails generator because I used Rails. If a merb/other framework (Ruby or non-Ruby) wants a similar generator, just ask. Its pretty simple - I copy over the rails_generators folder into a merb_generators folder in newjs and change some things based on your frameworks’ structure.

Alternate test suite support

If you like another test suite, and want it included in the generators, this might require some additional effort on your part. It probably has different mechanisms for launching runners etc; whereas I was able to steal the rake tests + support libraries from prototypejs. But, it can be done.

Peepcode

These tools will be discussed in animated detail in the forth coming Peepcode “JavaScript Unit Testing”.