In article <cel0la$2sto$1 / ulysses.noc.ntua.gr>,
George Moschovitis  <gm / navel.gr> 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