"Yohanes Santoso" <ysantoso-rubytalk / dessyku.is-a-geek.org> schrieb im Newsbeitrag news:877jseplp6.fsf / dessyku.is-a-geek.org... > Rando Christensen <eyez / illuzionz.org> writes: > > > The macro version has made the code much less clear in my mind, which is > > precisely the argument against macros in ruby. > > Actually, the example Jesse gave was probably bad. A macro, like any > other language construct, can be created to enhance clarity or > obfucate. Thus, one should not make a hasty judgement based on that > one example. > > How about this example (which I hope is a better example of > easy-with-macro,-hard-(impossible?)-without): > > Suppose we want to do self-documenting methods (not source file), > similar to docstring in emacs: > > An implementation with macro would look something like: > > def foo(arg) > "This method will return <code>arg</code>" > arg > end > > Sure, you can implement this without macro (trivial implementation): > > DOCSTRINGS={} > def def_with_docstring(klazz, method_name, docstring, arg_spec, body) > id = "#{klazz.to_s}##{method_name}" > DOCSTRINGS[id] = docstring > klazz.module_eval(%{def #{method_name}(#{arg_spec}) > #{body} > end}, __FILE__, 9999) # wish that there isn't > # anything on line 9999. > end This will print wrong file names for all methods not defined in that file. I'd prefer something like this: module DocMix def doc(item, text) (@docs ||= {})[item.to_s] = "#{item} defined in #{caller[0]}: #{text}" end def get_doc(item) @docs ? @docs[item.to_s] : nil end end class Class ; include DocMix end class Module ; include DocMix end class Foo doc :bar, "Method that prints hallo 'name'" def bar(name) puts "hallo #{name}" end end puts Foo.get_doc( :bar ) module Test doc :"Test.bar", "Method that prints hallo 'name'" def self.bar(name) puts "hallo #{name}" end end puts Test.get_doc( :"Test.bar" ) Of course one could easily add argument names etc. Personally I never needed Macros until now and I've yet to see a use case where I would really need them. > def_with_docstring(Object, "foo", "returns arg", "arg", "arg") > > Object.new.foo("hi") # => "hi" > > Yes, I am aware you can do more sophisticated implementation so you > can make the above nicer. Yet, as nice as it will be, it won't be as > simple as the example with macro; there will be quirkiness caused by > the language syntax. > > For example, rake has this in its documentation: "NOTE: Because of a > quirk in Ruby syntax, parenthesis are required on rule when the first > argument is a regular expression." > > Another example: I am not even sure you can turn the above example to > take lambdas as the body. Being able to take lambdas would be nice as > you can take advantage of your editor's syntax highlighting and > auto-indent. You could do that. But you couldn't define methods that receive a body as lamba that way. That's a restriction of define_method which you would have to use in this case. Regards robert