Oops! Hobo 0.4.2 released

Posted over 7 years back at The Hobo Blog

Um - little bit of a bug in 0.4.1. Let’s hope 0.4.3 is a more significant upgrade :-)

Oops! Hobo 0.4.2 released

Posted over 7 years back at The Hobo Blog

Um - little bit of a bug in 0.4.1. Let’s hope 0.4.3 is a more significant upgrade :-)

Hobo 0.4.1 released

Posted over 7 years back at The Hobo Blog

This release contains a variety of fixes and enhancements. One notable feature is support for RPC style “web-methods”. This gives you an easy way to expose methods on your model classes that don’t fit neatly into the REST/CRUD paradigm, e.g. reset_password. For the full low-down, see the change-log

Hobo 0.4.1 released

Posted over 7 years back at The Hobo Blog

This release contains a variety of fixes and enhancements. One notable feature is support for RPC style “web-methods”. This gives you an easy way to expose methods on your model classes that don’t fit neatly into the REST/CRUD paradigm, e.g. reset_password. For the full low-down, see the change-log

Seacoast Ruby UG First Meeting Tonight!

Posted over 7 years back at zerosum dirt(nap) - Home

If you’re in the seacoast NH area (north of Boston), don’t forget to attend the first meeting of the Seacoast Ruby/Rails User Group tonight from 7-9 at the UNH campus. Apparently there was such an overwhelming response that Scott had to move the location to Morse Hall in order to accommodate the additional heads. Wow, cool. More information and directions are on Scott’s blog. See you there!

Tom on Hobo on Ruby on Rails in Canada and London

Posted over 7 years back at The Hobo Blog

Just thought I’d let you know there are going to be a couple of opportunities to see me rambling on about Hobo. One soon and local, the other not so much.

On 9th February, there’s a Rails “mini-conf”, hosted by Skills Matter. Skills Matter are the training company who run the Rails course written by Chad Fowler and delivered by yours truly and others.

I’m also very happy to say I’ve been invited to present on Hobo at the Canada on Rails conference in October in Toronto. A big thank-you to Nathaniel Brown for the invite.

Really looking forward to both of these events!

p.s. Hobo 0.4.1 is just around the corner.

Tom on Hobo on Ruby on Rails in Canada and London

Posted over 7 years back at The Hobo Blog

Just thought I’d let you know there are going to be a couple of opportunities to see me rambling on about Hobo. One soon and local, the other not so much.

On 9th February, there’s a Rails “mini-conf”, hosted by Skills Matter. Skills Matter are the training company who run the Rails course written by Chad Fowler and delivered by yours truly and others.

I’m also very happy to say I’ve been invited to present on Hobo at the Canada on Rails conference in October in Toronto. A big thank-you to Nathaniel Brown for the invite.

Really looking forward to both of these events!

p.s. Hobo 0.4.1 is just around the corner.

FreeBSD 6.2 Released

Posted over 7 years back at zerosum dirt(nap) - Home

FreeBSD 6.2 was released this morning. Lots of bugfixes and new features, including official support for binary updates with freebsd-update. Cvsup away!

Railsbench gem updated

Posted over 7 years back at RailsExpress.blog

Today I’ve released a new gem version (0.9.1) of railsbench. It’s mainly a bug fix release for the installation problems discovered for 0.9.0.

However, there’s also a new script called generate_benchmarks, which can be used to generate and maintain the benchmark configuration file used by railsbench.

railsbench generate_benchmarks updates the benchmark configuration file with

  • a benchmark for each controller/action pair (named <controller>_<action>)
  • a benchmark for each controller combining all actions of the controller into one benchmark (named <controller>_controller)
  • a benchmark comprising all controllers (named all_controllers)

This should get you started benchmarking in no time ;-)

After generating the file, you will need to edit the benchmarks and replace routing placeholders (:id, :article_id, etc.) by actual values.

If you add new controllers/actions later in the development process, you can invoke railsbench generate_benchmarks again to add new items to the configuration file. The older entries will not be removed by this process.

Currently, generate_benchmarks only works for the 1.2 release candidate and edge Rails (but I’ll gladly accept patches to make it work with 1.1.6).

Happy benchmarking!

RailsConf 2007 Registration Opens 1st Week Of February

Posted over 7 years back at zerosum dirt(nap) - Home

This time around the event runs from May 17th to the 20th. Am I gonna go? I’m debating. It seems like a great opportunity to hear a bunch of great speakers, absorb some mad knoweldge, and meet like-minded Rubyists. Plus it’s in Portland Oregon (the other Portland), a city I’ve always wanted to visit, and a mere 2 hours from a good friend of mine in Eugene.

The thing that gives me pause is, of course, the cost. Registration is rumored to be a whopping $800 for the 4-day event this year, roughly double the 2006 event price. Ouch. Does this dramatic price hike reflect significantly increased offerings, or is it just because Rails has moved a bit closer to the mainstream — meaning that more corporate entities are capable of coughing up the usual exorbitant conference fees to send employees? Sigh. In either case, as a self-employed developer type that’s painful. Only half as painful as WWDC. But still, painful.

Of course, if you have the time and the skills, CD Baby is sponsoring a HackFest to send the top 20 patch contributors free of charge (inc hotel). You’ve got until the 22nd to make your impact as measured here. And yes, I’m a bit late in posting that news.

Blog Migration

Posted over 7 years back at Sporkmonger

Alright, that’s it. I’ve had it. Just got hit with another hundred or so spammy trackbacks.

I’m sick of Typo. Too much trackback spam, and no good way of defeating it with Typo. Typo doesn’t even let you disable trackbacks. It has an option for disabling it, but it doesn’t seem to actually do anything. Plus regular expressions and simple string blacklists that don’t match against the poster’s name, email address, or uri simply aren’t enough. It’s time to migrate to Mephisto. I’d been planning on sticking with Typo until GentleCMS was done and then rolling my own setup, but this is much too frustrating. So yeah, I’m starting the work required to switch over as of right now. Might take me a couple days because I have customizations to the Typo codebase, but if you have trouble leaving comments or if the site goes down entirely, you’ve probably just caught me in the middle of trying something. And apologies if any comments get lost in the fray.

I’ll probably end up implementing something similar to what Sam Ruby has going because a) it’s simple and b) seems to work.

Update: Now that I think about it, I might “reboot” the design while I’m at it. I found my missing spork the other day, so it’ll likely make a reappearance in the header image for the new design.

Update: It’s going to take longer than I thought to get the blog migrated. In the meantime, I’ve rather forcibly mangled Typo’s trackback support by rerouting trackbacks to the homepage. Didn’t feel like wading through Typo’s code when a one line patch to routes.rb would work. I’ll get everything working again later. The blog conversion has been largely delayed by TextDrive not answering support requests (grr) and by myself being preoccupied with work for a client. Some cool stuff that I can’t wait to show off.

Virtue

Posted over 7 years back at Ryan Tomayko's Writings

James Governor:

It does not mean I am reducing my commitment to RedMonk. Absolutely not. It does mean I am going to be giving some energy to some other things that are really important to me. Small things like – you know, the future of the planet.

Sometimes I wonder what the world would like if more people let their conscience get the better of them.

Surprise 10min Benchmark: eval, class_eval, instance_eval, define_method, bind

Posted over 7 years back at Wood for the Trees

What is the fastest way to dynamically define a method? define_method? class_eval? instance_eval? With strings or procs? Maybe we can pull out some arcane magic and use instance_method and bind (depending on what we want to do).

We all need to use some kind of eval at some point and, while it will not usually effect performance when used sparingly, sometimes it just has to make a serious appearance. When I saw how slow RSpec is in comparison to the venerable Test::Unit, I discovered the way it handles its contexts: each one is individually instance_eval’d into an empty ContextEvalModule. It isn’t the only reason for being slower, but it is one and one which can really mount up on big projects.

So, moving on from RSpec, Test::Unit and my baseline, MicroTest (see previous post), I became perversely interested in benchmarking all the ways of doing it and found some surprises.

Results (Ruby 1.8.4)

                            user     system      total        real
eval/str              112.540000   0.060000 112.600000 (112.615607)
instance_eval/str      99.510000   0.040000  99.550000 ( 99.564661)
class_eval/str        112.750000   0.060000 112.810000 (112.824374)
instance_eval/proc     56.750000   0.040000  56.790000 ( 56.802483)
class_eval/proc        56.440000   0.020000  56.460000 ( 56.464818)
define_method/class   112.420000   0.060000 112.480000 (112.489430)
define_method/send    111.540000   0.050000 111.590000 (111.610502)
def/unbind/bind        73.750000   0.060000  73.810000 ( 73.875800)
def                    52.670000   0.030000  52.700000 ( 52.705886)
method/bind            13.520000   0.010000  13.530000 ( 13.523194)

Analysis

I put it roughly in the order which I originally expected, with the slowest at the top.

The first thing that stunned me was the speed of define_method. It’s as slow as a snail. It’s practically eval, despite using a proc. I’ve been using it in preference before, thinking it was faster than any of the evals (proc or string). Apparently not.

The second revelation was how proc-based evals are about 50% faster than a def/unbind/bind cycle, which only has def as the evaluating part. That any eval is close to def is simply surprising. The instance_eval variety is the one used by RSpec, so I guess they picked the best one already.

The third shock was how slow def is! Granted, this is a lot of iterations, but it should be quicker than that, surely?

So it seems pretty plain that method unbinding as a tuning technique is rubbish, despite not evaluating anything, whereas a proc-based instance_eval or simple def are the clear winners.

But wait… what about Ruby 1.8.5?

Seeing the decrepitude of define_method made me wonder about the latest release of Ruby. I downloaded it, compiled it, got it working and ran the same bench:

Results (Ruby 1.8.5)

                            user     system      total        real
instance_eval/str     109.620000   0.050000 109.670000 (109.685393)
class_eval/str        113.840000   0.060000 113.900000 (113.910749)
eval/str              114.520000   0.060000 114.580000 (114.596238)
define_method/class    70.220000   0.040000  70.260000 ( 70.264506)
define_method/send     68.030000   0.040000  68.070000 ( 68.066688)
def/unbind/bind        73.690000   0.030000  73.720000 ( 73.741549)
instance_eval/proc     59.050000   0.030000  59.080000 ( 59.084445)
class_eval/proc        59.530000   0.030000  59.560000 ( 59.566885)
def                    52.870000   0.030000  52.900000 ( 52.895184)
method/bind            12.470000   0.010000  12.480000 ( 12.484069)

Anaylsis

I guess they fixed the problem and more besides. define_method is now marginally faster than def/unbind/bind (which has not budged an inch). I think I’ll continue to take the performance hit on define_method with 1.8.4, knowing I’ll want to upgrade later in the future and not change techniques.

The old recommendations hold true

  • instance_eval with a proc for class, instance or singleton evaluation
  • instance_eval for changing proc bindings
  • define_method for converting procs into methods
  • def for everything else
  • eval when you really know you need it

Note: These findings are only for def meth; true; end and may vary in complex cases.

Benchmark Code

require 'benchmark'

class A; def meth1; true; end; end

# defining using eval/class/instance
str = "def meth2; true; end"
a_binding = A.send(:binding)

# proc for class/instance
proc1 = Proc.new { def meth2; true; end }

# proc for define_method
$proc2 = Proc.new { true }

# unbound method for bind
um = A.instance_method(:meth1)

# number of iterations
n = 12000 * 600

Benchmark.bm(22) do |x|

  x.report('instance_eval/str') do
    for i in 1..n; A.instance_eval(str); end
  end

  x.report('class_eval/str') do
    for i in 1..n; A.class_eval(str); end
  end

  x.report('eval/str') do
    for i in 1..n; eval(str, a_binding); end
  end

  x.report('define_method/class') do
    for i in 1..n; class A; define_method(:meth2, &$proc2); end; end
  end

  x.report('define_method/send') do
    for i in 1..n; A.send(:define_method, :meth2, &$proc2); end
  end

  x.report('def/unbind/bind') do
    for i in 1..n
      class A; def meth2; true; end; end
      A.instance_method(:meth2).bind(A.new)
    end
  end

  x.report('instance_eval/proc') do
    for i in 1..n; A.instance_eval(&proc1); end
  end

  x.report('class_eval/proc') do
    for i in 1..n; A.class_eval(&proc1); end
  end

  x.report('def') do
    for i in 1..n; class A; def meth2; true; end; end; end
  end

  x.report('method/bind') do
    for i in 1..n; um.bind(A.new); end
  end

end

Surprise 10min Benchmark: eval, class_eval, instance_eval, define_method, bind

Posted over 7 years back at Wood for the Trees

What is the fastest way to dynamically define a method? define_method? class_eval? instance_eval? With strings or procs? Maybe we can pull out some arcane magic and use instance_method and bind (depending on what we want to do).

We all need to use some kind of eval at some point and, while it will not usually effect performance when used sparingly, sometimes it just has to make a serious appearance. When I saw how slow RSpec is in comparison to the venerable Test::Unit, I discovered the way it handles its contexts: each one is individually instance_eval’d into an empty ContextEvalModule. It isn’t the only reason for being slower, but it is one and one which can really mount up on big projects.

So, moving on from RSpec, Test::Unit and my baseline, MicroTest (see previous post), I became perversely interested in benchmarking all the ways of doing it and found some surprises.

Results (Ruby 1.8.4)

                            user     system      total        real
eval/str              112.540000   0.060000 112.600000 (112.615607)
instance_eval/str      99.510000   0.040000  99.550000 ( 99.564661)
class_eval/str        112.750000   0.060000 112.810000 (112.824374)
instance_eval/proc     56.750000   0.040000  56.790000 ( 56.802483)
class_eval/proc        56.440000   0.020000  56.460000 ( 56.464818)
define_method/class   112.420000   0.060000 112.480000 (112.489430)
define_method/send    111.540000   0.050000 111.590000 (111.610502)
def/unbind/bind        73.750000   0.060000  73.810000 ( 73.875800)
def                    52.670000   0.030000  52.700000 ( 52.705886)
method/bind            13.520000   0.010000  13.530000 ( 13.523194)

Analysis

I put it roughly in the order which I originally expected, with the slowest at the top.

The first thing that stunned me was the speed of define_method. It’s as slow as a snail. It’s practically eval, despite using a proc. I’ve been using it in preference before, thinking it was faster than any of the evals (proc or string). Apparently not.

The second revelation was how proc-based evals are about 50% faster than a def/unbind/bind cycle, which only has def as the evaluating part. That any eval is close to def is simply surprising. The instance_eval variety is the one used by RSpec, so I guess they picked the best one already.

The third shock was how slow def is! Granted, this is a lot of iterations, but it should be quicker than that, surely?

So it seems pretty plain that method unbinding as a tuning technique is rubbish, despite not evaluating anything, whereas a proc-based instance_eval or simple def are the clear winners.

But wait… what about Ruby 1.8.5?

Seeing the decrepitude of define_method made me wonder about the latest release of Ruby. I downloaded it, compiled it, got it working and ran the same bench:

Results (Ruby 1.8.5)

                            user     system      total        real
instance_eval/str     109.620000   0.050000 109.670000 (109.685393)
class_eval/str        113.840000   0.060000 113.900000 (113.910749)
eval/str              114.520000   0.060000 114.580000 (114.596238)
define_method/class    70.220000   0.040000  70.260000 ( 70.264506)
define_method/send     68.030000   0.040000  68.070000 ( 68.066688)
def/unbind/bind        73.690000   0.030000  73.720000 ( 73.741549)
instance_eval/proc     59.050000   0.030000  59.080000 ( 59.084445)
class_eval/proc        59.530000   0.030000  59.560000 ( 59.566885)
def                    52.870000   0.030000  52.900000 ( 52.895184)
method/bind            12.470000   0.010000  12.480000 ( 12.484069)

Anaylsis

I guess they fixed the problem and more besides. define_method is now marginally faster than def/unbind/bind (which has not budged an inch). I think I’ll continue to take the performance hit on define_method with 1.8.4, knowing I’ll want to upgrade later in the future and not change techniques.

The old recommendations hold true

  • instance_eval with a proc for class, instance or singleton evaluation
  • instance_eval for changing proc bindings
  • define_method for converting procs into methods
  • def for everything else
  • eval when you really know you need it

Note: These findings are only for def meth; true; end and may vary in complex cases.

Benchmark Code

require 'benchmark'

class A; def meth1; true; end; end

# defining using eval/class/instance
str = "def meth2; true; end"
a_binding = A.send(:binding)

# proc for class/instance
proc1 = Proc.new { def meth2; true; end }

# proc for define_method
$proc2 = Proc.new { true }

# unbound method for bind
um = A.instance_method(:meth1)

# number of iterations
n = 12000 * 600

Benchmark.bm(22) do |x|

  x.report('instance_eval/str') do
    for i in 1..n; A.instance_eval(str); end
  end

  x.report('class_eval/str') do
    for i in 1..n; A.class_eval(str); end
  end

  x.report('eval/str') do
    for i in 1..n; eval(str, a_binding); end
  end

  x.report('define_method/class') do
    for i in 1..n; class A; define_method(:meth2, &$proc2); end; end
  end

  x.report('define_method/send') do
    for i in 1..n; A.send(:define_method, :meth2, &$proc2); end
  end

  x.report('def/unbind/bind') do
    for i in 1..n
      class A; def meth2; true; end; end
      A.instance_method(:meth2).bind(A.new)
    end
  end

  x.report('instance_eval/proc') do
    for i in 1..n; A.instance_eval(&proc1); end
  end

  x.report('class_eval/proc') do
    for i in 1..n; A.class_eval(&proc1); end
  end

  x.report('def') do
    for i in 1..n; class A; def meth2; true; end; end; end
  end

  x.report('method/bind') do
    for i in 1..n; um.bind(A.new); end
  end

end

Introducing: MicroTest

Posted over 7 years back at Wood for the Trees

Something I cooked up in an hour for bootstrap testing a testing framework.

If anyone actually wants me to maintain it, just give a shout and I’ll gemify it.



# A super-small testing suite.
# Just two ways to assert:
#   expect { (whatever must return true) }
#   do_not_expect { (whatever must return false) }
#
# A microtest looks like this:
#
#   class BinaryMicroTest < MicroTest
#     def should_exit_cleanly
#       expect do
#         `ruby #{myexec}`
#         $? == 0
#       end
#     end
#   end
#
class MicroTest

  class MicroFailure < StandardError; end

  class << self

    attr_accessor :passed, :failed, :executed, :expectations, :planned, :plan, :failures

    def run
      init
      execute
      report
    end

    def init
      self.passed, self.failed, self.executed, self.expectations = 0, 0, 0, 0
      self.planned, self.plan = harvest
      self.failures = []
    end

    def harvest
      plan = []
      ObjectSpace.each_object(Class) do |k|
        if k.respond_to?(:superclass) && k.superclass == MicroTest
          plan << [k, k.instance_methods.grep(/^should_/)]
        end
      end
      planned = plan.inject(0) { |c, ary| c += ary[1].size; c }
      [planned, plan]
    end

    def execute
      puts "Running #{self.planned} test(s)..."
      self.plan.each do |klass, tests|
        tests.each do |test|
          instance = klass.new
          r = catch_failures(klass, test) { instance.send(test) }
          if r
            self.passed += 1
            print "."
            STDOUT.flush
          else
            self.failed += 1
            print "F"
            STDOUT.flush
          end
          self.expectations += instance.expectation_count
          self.executed += 1
        end
      end
    end

    def catch_failures(klass, test)
      begin
        yield
        true
      rescue Exception => e
        self.failures << [klass, test, e]
        false
      end
    end

    def report
      puts "\n\n"
      puts "%d planned, %d executed, %d passed, %d failed.\n%d expectations found." %
        [self.planned, self.executed, self.passed, self.failed, self.expectations]
      unless self.failures.empty?
        puts "\nFAILURE REPORT\n"
        self.failures.each { |f| report_failure(f) }
      end
    end

    def report_failure(f)
      puts "Suite: #{f[0]}\nTest: #{f[1]}\nException: #{f[2].class}\nMessage: #{f[2].message}"
      puts ("\t" << f[2].backtrace.join("\n\t"))
    end

  end

  attr_accessor :expectation_count

  def initialize
    self.expectation_count = 0
  end

  def expect(&block)
    self.expectation_count += 1
    raise MicroFailure, "should be true" unless block.call
  end

  def do_not_expect(&block)
    self.expectation_count += 1
    raise MicroFailure, "should be false" if block.call
  end

end

at_exit do
  MicroTest.run
end

Just dump that in a helper file and require it, as per normal Test::Unit practices.