In article <87brt5wz83.fsf / ethereal.dyndns.org>, Nolan J. Darilek <nolan_d / bigfoot.com> wrote: >I've begun working on a music-related ruby project, and recently I've >been pondering the idea of a music composition environment somewhat >similar to cm, clm and friends for lisp, but in ruby instead. > >Today I was thinking about how ruby blocks make constructing >domain-specific languages a snap. I've been reading Lisp as a Second >Language at http://www.ircam.fr/equipes/repmus/LispSecondLanguage/, a >Lisp tutorial for musicians, and was considering using a list-based >structure for storing music. I sorta envisioned the language as >looking something like: > >clef do > measure("4/4") do > c d e f g a b c > chord do > c e g > end > end >end > >In this example, a-g are methods returning note objects. > >What I'd like is to have that return a list like so: > >["c", "d", "e", "f", "g", "a", "b", "c", ["c", "e", "g"]] > I did a little more work on this; now I don't have to pass in a list to the notes from within the chord block: module Music def a(list=@tmp_notes) list << "a" end def b(list=@tmp_notes) list << "b" end def c(list=@tmp_notes) list << "c" end def d(list=@tmp_notes) list << "d" end def e(list=@tmp_notes) list << "e" end def f(list=@tmp_notes) list << "f" end def g(list=@tmp_notes) list << "g" end def clef puts "...In Clef..." yield @notes = @tmp_notes @notes << @chord_notes unless @chord_notes.empty? return @notes end def measure(time) puts "...In Measure..." yield end def chord #make a local copy of @tmp_notes tmpnotes = @tmp_notes.dup @tmp_notes.clear puts "...In Chord..." yield @chord_notes @chord_notes = @tmp_notes #restore @tmp_notes @tmp_notes = tmpnotes end def notes @notes end end class Song include Music def initialize @notes = [] @chord_notes=[] @tmp_notes = [] end end class MySong < Song include Music def initialize super clef do measure("4/4") do c; d; e; f; g; a; b; c; chord do c; d; g; end end end end end mysong = MySong.new p mysong.notes So that gets rid of some of the ugliness that the user of your music language has to know (you want them to not have to know Ruby at all), but the super is still there. Perhaps you could do something like this instead of subclassing Song, you could do (untested): Defined by you: class Song include Music def initialize @notes = [] @chord_notes=[] @tmp_notes = [] yield end end Defined by user in a different file: my_song= Song.new { clef do measure("4/4") do c; d; e; f; g; a; b; c; chord do c; d; g; end end end } The advantage being that you can eliminate the need for the user to have to define a class and call super. You could even add more methods to either Song or Music so that you could do: my_song.play ....but I'm not sure that will work; the block being passed to Song.new has to know about all of the methods we're using in it (a-f refer to @temp_list which doesn't have a context in this block). There's probably some way of doing this... Phil