From: Robert Klemme Date: 2011-01-26T17:07:20+09:00 Subject: Re: Surely there's a better way to do this... (implementing a DSL) On Tue, Jan 25, 2011 at 6:33 PM, Tony Arcieri wrote: > On Tue, Jan 25, 2011 at 7:19 AM, Robert Klemme > wrote: > >> First thing that strikes me odd is that you define methods on the >> singleton class, i.e. instance methods of the newly created class. >> What do you need a class for then - especially since your new class >> inherits Object (which means, it does not inherit particular instance >> functionality)? > > > Because I'm building these classes for another API, namely Resque. I'm > creating a DSL for building Resque jobs, which the documentation defines > thusly: > > Resque jobs are Ruby classes (or modules) which respond to > the perform method. Here's an example: > > class Archive >  @queue = :file_serve > >  def self.perform(repo_id, branch = 'master') >    repo = Repository.find(repo_id) >    repo.create_archive(branch) >  end > end > > > So unfortunately I can't change the form of the classes I'm trying to > generate (with the possible exception of changing them into modules) Then it seems this would do def awesome_mcjobify(state, options = {}, &action) cl = Class.new do def self.perform(id) @action[@cl.find(id)] end end cl.instance_variable_set "@action", action cl.instance_variable_set "@cl", @subject_class cl end However, it seems that https://github.com/defunkt/resque uses classes in order to be able to distribute them to different machines. In that case you would need to make sure the class has a name and is known at all nodes. In that case it might be wise to also add a String argument to the method call. Btw, if my assumption is correct you might get away with simple instances that implement important methods (#name for example) and are assigned to constants which reflect their name. Side note: code distribution is the Achilles heel of distributed job systems. You either have to distribute code along with the request which bloats queues and introduces security risks. Or you distribute it via some other channel and then you can get typical versioning issues... Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/