"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