Henry Savr <hsavr@yahoo.com> writes:
<a desire for macros in ruby>
What about this? It's still a far cry from lisp macros, as it only
lets you define macros that work at the module level, and you need to
appropriately quote the input to a macro yourself, but I think with a
bit more reworking we could get "macros" to work at whatever level was
desired.
class Module
def defmacro(symbol, &block)
methodproc = Proc.new {|*a|self.class_eval(block.call(*a))}
self.send(:define_method, symbol, methodproc)
end
# Example macro that does what was mentioned in the long request:
defmacro(:var){|name,init|%Q{
def #{name}
@#{name} = #{init.inspect} unless defined? @#{name}
@#{name}
end
def #{name}=(val)
@#{name}=val
end
}}
# A silly macro - creates some number of attributes all
# with the same prefix, and initial values nil
defmacro(:varfamily){|name,n|
(1..n).map{|i|"var :#{name}_#{i}"}.join("\n")
}
end
Now let's test this out:
irb(main):033:0> class Foo; varfamily :foo,10; end
=> nil
irb(main):034:0> g = Foo.new
=> #<Foo:0x299b668>
irb(main):036:0> g.methods.select{|m|m=~/^foo/}.sort
=> ["foo_1", "foo_10", "foo_10=", "foo_1=", "foo_2", "foo_2=",
"foo_3", "foo_3=", "foo_4", "foo_4=", "foo_5", "foo_5=",
"foo_6", "foo_6=", "foo_7","foo_7=", "foo_8", "foo_8=",
"foo_9", "foo_9="]
irb(main):037:0> g.foo_5
=> nil
irb(main):038:0> g.foo_5=6
=> 6
irb(main):039:0> g.foo_5
=> 6
I still think that you're almost always better off using some already
present meta-programming tool, but if you really want a string-parsing
macro soup, this might do the trick.
···
--
s=%q( Daniel Martin -- martin@snowplow.org
puts "s=%q(#{s})",s.map{|i|i}[1] )
puts "s=%q(#{s})",s.map{|i|i}[1]