From: ptkwt@... (Phil Tomson) Date: 2004-08-03T03:51:38+09:00 Subject: Re: Macros in Ruby In article , George Moschovitis wrote: >Hello everyone, > >one of the features of the LISP family of languages that is missing from >Ruby are macros. I think they are useful on a lot of occasions so >I would like to see Ruby support macros in the future. > >However i think it is quite easy to emulate some form of macro >functionality in Ruby. Here is some simple code: > >macros.rb: >---------- > >$__macros__ = {} >$__required__ = {} > >module Kernel > >alias_method :old_require, :require >def require(path) > return if $__required__[path] > > source = open(path) { |f| > f.sysread(f.stat().size()) > } > > # parse macro > source.gsub!(/defmacro\s*\/(.*?)\/\s(.*?)endmacro/m) { > $__macros__[Regexp.new($1)] = $2 ; "" > } > > # expand macros > $__macros__.each { |match, replace| > source.gsub!(match, replace) > } > > $__required__[path] = true > > eval(source) >end > >end > >require "test1.rb" >require "test2.rb" > > >test1.rb: >--------- > >defmacro /my_macro\((.*)\)/ > begin > my_function(\1) > rescue => ex > puts ex > end >endmacro > ># php style foreach >defmacro /foreach\s*\((.*)\s*as(.*)\)/ > for \2 in \1 >endmacro > >def my_function(str) > puts str >end > >class TestClass > def another_test > words = %w{ simple test } > foreach(words as word) > puts k > end > end >end > > >test2.rb: >--------- > >value = "Hello World!" >my_macro(value) > >numbers = [1, 2, 3, 4] > >foreach (numbers as i) > puts i >end > >a = TestClass.new >a.another_test() > > > >Once again i was suprised to find out that Ruby is so powerful! > >However I would like to hear your opinion on this code. Is there any >problem I have overlooked? Is there a better implementation? Could this >be better designed? Another comment: maybe instead of redefining 'require' you should just have another method on kernel, something like 'load_macro' or 'require_macro'? This would make it clear that you are loading code which contains macros. Perhaps even the file extension should be different for these files to avoid confusion (*.rbm?). Also, right now you can only define these macros in files that get required, maybe you should also allow for the definition of macros in strings or here-docs? Phil