 |

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
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
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
Posted @ 5/7/2006 4:09 AM
http://www.odeo.com/audio/306705/view
-
# re: "DSL" mechanisms in Ruby
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
-
Posted @ 5/7/2006 10:50 PM
buy tramadol online for cheap at http://tramadol.onlinedrugorder.com/ 45
-
# re: "DSL" mechanisms in Ruby
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
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
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
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
Posted @ 5/10/2006 4:03 AM
Is COBOL a DSL?
-
# re: "DSL" mechanisms in Ruby
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
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
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
Posted @ 5/11/2006 2:41 AM
Woke up refreshed and realized class_eval could be replaced with define_method.
|
|