About UsCommunityTrainingContent DevelopmentContact

Blogs
Pluralsight
Course Schedule
Scott Allen
Craig Andera
Mark Baciak
Don Box
Keith Brown
John CJ
Tim Ewald
Jon Fancey
Jon Flanders
Vijay Gajjala
Kirill Gavrylyuk
Ian Griffiths
Martin Gudgin
Jim Johnson
John Justice
Mike Henderson
Joe Hummel
Matt Milner
Ted Neward
Fritz Onion
Brian Randell
Jeffrey Schlimmer
Aaron Skonnard
Dan Sullivan
Herb Sutter
Doug Walter
Jim Wilson
Mike Woodring

My Links
Home
Contact
Login

Blog Stats
Posts - 339
Stories - 0
Comments - 1974
Trackbacks - 549

VSers
Anson Horton(rss)
Chuck Jazdzewski
Cyrus Najmabadi(rss)
Dan Fernandez
Gareth Jones(rss)
Gus Perez(rss)
Herb Sutter(rss)
Jack Greenfield(rss)
Jay Bazuzi(rss)
Keith Short(rss)
Matt Warren(rss)
Peter Hallam(rss)
Scott Wiltamuth(rss)
Steve Cook(rss)
Stuart Kent(rss)

WinFXers
Adam Nathan (rss)
Aditya Bhandarkar(rss)
Akash Jeevan Sagar(rss)
Bruce Williams(rss)
Chris Anderson(rss)
Daniel Lehenbauer
Dave Green(rss)
Dennis Pilarinos(rss)
Dharma Shukla(rss)
Doug Purdy(rss)
Doug Walter(rss)
Filipe Fortes
Greg Schechter
Henry Hahn
Hervey Wilson(rss)
James Conrad(rss)
Jeff Schlimmer(rss)
Jim Johnson(rss)
Jurgen Thelin(rss)
Karsten Januszewski
Kavita Kamani(rss)
Kenny Wolf(rss)
Kirill Gavrylyuk(rss)
Lauren Lavoie
Martin Gudgin(rss)
Mike Vernal(rss)
Nick Kramer
Omri Gazitt(rss)
Rob Relyea
Savas Parastatidis
Steve Maine(rss)
Tim Sneath(rss)
Yasser Shohoud(rss)

WinFXies
Aaron Skonnard(rss)
BenjaminM
Christian Nagel(rss)
Christian Weyer(rss)
Clemens(rss)
David Chappell
Ingo Rammer(rss)

Z through A
Chris Brumme(rss)
Jan Gray(rss)
Jon Udell
Nick Gall(rss)
Paul Graham(rss)
Petzold

Archives
May, 2008 (2)
Apr, 2008 (1)
Feb, 2008 (4)
Jan, 2008 (6)
Dec, 2007 (2)
Nov, 2007 (13)
Oct, 2007 (9)
Aug, 2007 (3)
May, 2007 (6)
Apr, 2007 (2)
Mar, 2007 (5)
Feb, 2007 (2)
Jan, 2007 (13)
Dec, 2006 (8)
Oct, 2006 (2)
Aug, 2006 (1)
Jul, 2006 (3)
Jun, 2006 (11)
May, 2006 (15)
Apr, 2006 (6)
Mar, 2006 (7)
Feb, 2006 (2)
Jan, 2006 (9)
Dec, 2005 (13)
Nov, 2005 (4)
Oct, 2005 (12)
Sep, 2005 (15)
Aug, 2005 (7)
Jul, 2005 (32)
Jun, 2005 (10)
May, 2005 (8)
Apr, 2005 (18)
Mar, 2005 (4)
Feb, 2005 (24)
Jan, 2005 (5)
Dec, 2004 (6)
Nov, 2004 (20)
Oct, 2004 (24)
Sep, 2004 (5)

Image Galleries
People



I'm trying to get the zen of building DSLs using Ruby. After reading a dozen or so pieces referenced by my favorite search engine, I have a feeling I'm still not quite getting it.
 
I grok the various forms of eval (eval, module_eval and instance_eval) as well as the extremely cool Binding feature. 
 
I've also seen BlankSlate for eviscerating an object of the methods it picks up from Object.
 
At the end of the day, however, it looks like the whole Ruby/DSL thing is just inventive use of eval + some clever string munging, both of which are pretty doable in Javascript or Python (or even (gasp) C# using the CodeDOM compiler).
 
I'd love nothing more than for the Ruby folks to point me in the right direction. 
 
I met someone at the MS Tech Summit last month who's writing a book on this - perhaps he reads my blog and will give me the clue(s) I need.
posted on Sunday, May 07, 2006 2:35 AM

  • # re: "DSL" mechanisms in Ruby
    Don Box
    Posted @ 5/6/2006 8:37 PM
    BTW, my favorite example of a Ruby/DSL is John Lam's CIL DSL: http://www.iunknown.com/articles/2005/12/05/refining-the-ruby-cil-dsl

  • # re: "DSL" mechanisms in Ruby
    Paul Brown
    Posted @ 5/6/2006 9:52 PM
    One of the aspects that makes Ruby nice for DSLs (IMHO) is the flexibility on use of parentheses in invocations. It seems like a trivial thing, but parentheses are more for machines than for people.
  • # RubyConf 2005 - DSL's by Jim Weirich
    Sam Ruby
    Posted @ 5/7/2006 4:09 AM
    http://www.odeo.com/audio/306705/view
  • # re: "DSL" mechanisms in Ruby
    Ilya Baimetov
    Posted @ 5/7/2006 11:25 AM
    The best Ruby/DSL example I've seen so far is Rake.

    This presentation (by the author) does a very good job explaining whatr and why -
    http://jimweirich.umlcoop.net/articles/buildingwithrake/index.html

    MartinFowler wrote about it - http://www.martinfowler.com/articles/rake.html

    The project is at - http://rake.rubyforge.org/

    Enjoy

  • # tramadol
    tramadol
    Posted @ 5/7/2006 10:50 PM
    buy tramadol online for cheap at http://tramadol.onlinedrugorder.com/ 45
  • # re: "DSL" mechanisms in Ruby
    Neal Ford
    Posted @ 5/9/2006 5:28 AM
    Don -

    I'm the guy you talked to at MTS06 about DSL's. You're right: I'm reading your blog.

    The features you mention are important, but other Ruby features provide a nicer bed for DSL's. One of the key characteristics is the loose syntax rules (mentioned by another commenter): leaving parens off sound trivial, but consider this DSL, written in Ruby, by one of my co-workers:

    if the '$5-$10 Limit' list is more than 12 then notify the floor to open
    if the '$1-$2 No Limit' list is more than 15 then notify the floor to open
    if the '$5-$10 Limit' list is more than 8 then notify the brush to announce
    if the '$1-$2 No Limit' list is more than 10 then notify the brush to announce

    Yes, this is Ruby code, using a combination of method_missing, flexible parameter semantics, and multiple contexts. In fact, the blog entry where Jay describes this isn't even about the cool language elements, it's about executing this source code in different contexts (one context notifies employees, another tells the infrastructure folks to set up new tables, etc.) You can read the entire description at http://jayfields.blogspot.com/2006/05/executing-internal-dsl-in-multiple.html.

    It's not just a few language features in Ruby that enable DSL's, it's the combination of lots of features. You can created DSL's in strongly typed languages (I have examples in Java, C#, and others) but it's hard (outside of Lisp) to create languages that are indistinguishable from text files that your business analyst might read (and write).

    Three of my co-workers and myself are writing a book for Pragmatic Press on building internal DSL's in Ruby, and it will contain lots of examples of utilizing Ruby to create languages that don't look like source code, but look a lot like a problem domain. That's encapsulation, not just a tree of objects.
  • # re: "DSL" mechanisms in Ruby
    James Webster
    Posted @ 5/9/2006 3:32 PM
    "it's hard (outside of Lisp) to create languages that are indistinguishable from text files that your business analyst might read (and write)."

    I appreciate this as being the holy grail of DSLs, but consider that there are still underlying syntax rules that must be followed. Will the compiler/interpreter spit out syntax errors that will be intelligible enough for a business analyst to decode when an inevitable mistake is made?
  • # re: "DSL" mechanisms in Ruby
    Jon Tirsen
    Posted @ 5/9/2006 10:56 PM
    "but consider that there are still underlying syntax rules that must be followed. Will the compiler/interpreter spit out syntax errors that will be intelligible enough for a business analyst to decode when an inevitable mistake is made?"

    This is why intentional is the next logical steps after Ruby DSLs. Ruby allows for extremely fluid and expressive syntaxes due to exploiting some hacks and quirks in the language. (Almost completely unsurpassed except for perhaps Dylan or some purely academic languages. No, Neal, you can't even do most of this in Lisp as the C-exp braces/spaces still gotta be there to some extent.) But it doesn't guide the writer into writing the correct thing. With intentional a language author can actually design what is valid syntax in what contexts and so forth. This will guide the writer into writing proper expressions in the language including syntax highlighting, completion, error highlighting and so forth.
  • # re: "DSL" mechanisms in Ruby
    Jim Weirich
    Posted @ 5/10/2006 3:28 AM
    "[...] is just inventive use of eval + some clever string munging"

    Try imitating the Builder library (see http://onestepback.org/index.cgi/Tech/Ruby/BuilderObjects.rdoc for details) in Python. I think it demonstrates that the whole Ruby/DSL thing is more than just clever string manipulation.

    And its not just a Ruby thing. Builder itself was itself stolen from Groovy. I suspect it is doable in JavaScript, but I doubt you will get a useful version in either Java or Python. I don't know enough about C# to say one way or the other.
  • # re: "DSL" mechanisms in Ruby
    Christian Mogensen
    Posted @ 5/10/2006 4:03 AM
    Is COBOL a DSL?
  • # re: "DSL" mechanisms in Ruby
    assaf
    Posted @ 5/10/2006 7:56 AM
    Why not start with a use case?

    I can't imagine how a random combination of instance_eval and define_method leads to a DSL. But I have a DSL that uses just these two. And saves me a lot of coding.

    30.minutes + 5.seconds is a DSL that doesn't require any Ruby trickery, it just relies on the simple syntax.

    But some DSLs require crafty combinations of binding procs, defining methods from procs, removing others, responding to method_missing, creating context objects for instance_eval, etc.

    Either way, the features of the language are only as interesting as the DSLs you can create out of them, so why not start there?
  • # re: "DSL" mechanisms in Ruby
    James Logan
    Posted @ 5/10/2006 4:17 PM
    Jon Tirsen said

    "No, Neal, you can't even do most of this in Lisp as the C-exp braces/spaces still gotta be there to some extent."

    Really? Emulating the dot and space conventions of ruby is trivial in scheme/lisp. What exactly is impossible?
  • # re: "DSL" mechanisms in Ruby
    Christian Romney
    Posted @ 5/10/2006 5:35 PM
    Here's an amateurish DSL I've been toying with in my head. Note I have no idea whether the code actually executes, I typed it in Vim and pasted it here. The idea is how we can take English language constructs like reflexive verbs and predicates and translate those things with very little code to enable cool syntaxes.

    <pre>
    class ApplicationController < ActionController::Base
    # Reflexive verbs just return their arguments
    [:am, :is, :was, :are, :were, :has].freeze.each do |verb|
    class_eval("def #{verb.to_s}(arg); arg; end")
    end

    # Predicate messages contain a single (string) placeholder for formatting
    # If an instance is used with these, it should define a to_s that makes sense
    {
    :deleted => "The item you requested was deleted.",
    :expired => "Item '%s' has expired.",
    :created => "Item '%s' was created successfully.",
    :updated => "Item '%s' was updated successfully."
    }.freeze.each_pair do |name, value|
    class_eval("def #{name.to_s}; #{value}; end")
    end

    # DSL-ish notifications. People are notified of messages via a given delivery method.
    def notify(person, delivery, message)
    case delivery[:by].to_s
    when 'flash_message': flash[:notice] = message
    when 'email': ItemMailer.deliver_notification(person, message)
    end
    end
    end

    class ItemController < ApplicationController
    # This method flexes our DSL's muscles
    def delete
    subscribers = specified_item.subscribers
    specified_item.destroy

    subscribers.each do |subscriber|
    notify user, :by => :email, specified_item was deleted
    end
    end

    private
    # Uses an instance variable so we only incur the database hit once
    # If a predicate message is given, returns a formatted message,
    # otherwise returns the item itself
    def specified_item(predicate)
    @item ||= Item.find(params[:item])
    if predicate
    predicate % @item
    else
    @item
    end
    end
    end
    </pre>

    Apologies in advance if this looks like sh*t, your comment system doesn't have preview functionality.
  • # re: "DSL" mechanisms in Ruby
    Christian Romney
    Posted @ 5/11/2006 2:41 AM
    Woke up refreshed and realized class_eval could be replaced with define_method.
Title  
Name  
Url
Comments   
Please enter the code you see below. what's this?
This CAPTCHA image helps deter automated scripts that submit comment spam. In essence, it helps us determine that you are indeed a human instead of script.

 
   
 
© 2004 Pluralsight.
Visual Design by Studio Creativa
Privacy Policy