Meta methods to govern meta data?

D

Duane Johnson

I was intrigued by one of Matz's "Wild and Crazy Ideas" at RubyConf--
the inclusion of meta data in the comments section before a method
definition.

This got me thinking about the need for metadata and Ruby's fabulous
introspective capabilities and I wondered if it might be better to
have a governing "metamethod" for each method. Actually, more like
accessor metamethods. These metamethods would be in charge of
setting or getting key/value pairs describing things about the method
it is associated with:

# Returns double the input
def double(i)
i * 2
end

meta :double, :require => 'i.is_a? Fixnum'
meta :double, :comments
=> 'Returns double the input'

I don't quite like the syntax yet, (probably because we don't really
have a facility yet to talk about methods like this); however, I do
like the flexibility provided. Perhaps we could make a new syntax
like this:

def double>require(i)
i.is_a? Fixnum
end

def double>comment(original_comment)
"Haha! I can over-ride the comment."
end

And we could even do some cool stuff like custom namespace selectors:

def double>visibility(looking_at_me)
[Object, ActiveRecord].include? looking_at_me
end

(i.e. the method would be called prior to any reference to 'double'
and it would return 'true' if it is visible from within the caller's
scope / namespace).

We could even talk about meta-metamethods:

def double>visibility>comment
"Comment for the 'double>visibility' metamethod"
end

Duane Johnson
(canadaduane)
 
A

Adam Sanderson

I think you could extend Object to define something working like this:

comment "Doubles the number"
params :n => "Number to be doubled"
def double(n)
n * 2
end

Object could define 'comment' and 'params' and other metadata functions
(or annotations, it's just symantics) to store those values and apply
them to the next method defined.

Maybe I'll try and whip it up tonight?
.adam sanderson
 
G

gwtmp01

I think you could extend Object to define something working like this:
comment "Doubles the number"
params :n => "Number to be doubled"
def double(n)
n * 2
end

It seems to me that if you want to associate annotations with a
particular method they need to be syntactically connected to the
def/end block. In your example there is no way to do that unless
you are proposing that comment and params etc. all become keywords.
I'd like to avoid that type of keyword explosion.

Thinking out loud...

The syntax of a method definition already has a structure that admits
to additional "clauses":

def name(arg1, arg2)
# body
rescue
# code
ensure
# code
end

Why not extend this to something like:

def name(arg1, arg2)
notes
comment "This is a comment"
body
# body
rescue
# code
ensure
# code
end

Alternatively you could put the notes at the end to avoid
the addition of the 'body' keyword.

def name(arg1, arg2)
# do something
notes
comment "This is an example"
end

Another variation would be to have the annotation keyword
be an alternate syntax for the start of a method definition:

notes
description "This method takes two arguments"
status :experimental
def name(arg1,arg2)
# code
ensure
# code
end

There is the question of the syntax of the text between
'notes' and 'def'. Probably best to reuse the existing
method syntax but treat the "methods" that appear between
'notes' and 'def' as no-ops.

A similar syntax could be used to annotate classes:

notes
description "This is an annotated class"
author "Gary Wright"
class Sample

notes
"This is an annotated method"
def foo
end
end

For what it is worth, this is very similar to Eiffel's "indexing"
clause.

Gary Wright




Gary Wright
 
T

Trans

It's a plesant notation, but a couple issues with the ideas Gary
presents.

* How to dynamically set annotations? Even with this nice looking
notation you would still need a way to do via normal methods.

* It's important to allow annotations for methods that do not
neccessarily exit. In this way annotations would be reusable. For
example here is what you can do with facets/annotation.rb

module MyAnnotations
ann :foo, :comment => "foo is alwasy an example"
end

class MyClass
include MyAnnotations

ann self, :comment => "This is an annotated class."

def foo
puts "foo"
end

ann :foo, :author => "trans"

end

MyClass.ann.foo.author #=> "trans"
MyClass.ann.foo.comment #=> "foo is alwasy an example"
MyClass.ann.self.comment #=> "This is an annotated class."
MyClass.annotation.comment #=> "This is an annotated class."

T.
 
D

David A. Black

Hi --

I was intrigued by one of Matz's "Wild and Crazy Ideas" at RubyConf--the
inclusion of meta data in the comments section before a method definition.

This got me thinking about the need for metadata and Ruby's fabulous
introspective capabilities and I wondered if it might be better to have a
governing "metamethod" for each method. Actually, more like accessor
metamethods. These metamethods would be in charge of setting or getting
key/value pairs describing things about the method it is associated with:

# Returns double the input
def double(i)
i * 2
end

meta :double, :require => 'i.is_a? Fixnum'

It seems awkward (even leaving duck-typing issues aside :) to have a
constraint like that stored in a kind of eval string, rather than just
executed as part of the method. I'm not sure what's gained.
meta :double, :comments
=> 'Returns double the input'

In some ways I prefer going in the other direction -- that is, letting
the method be its own comment as much as possible. I can't help
thinking that part of the beauty of the language is that

def double(i)
i * 2
end

is so complete, and so completely transparent. I'd be loathe to add
even one line of comment to it, and even more so to add a separate
method call ("meta") to store comments.

I understand (a) that this was just an example, and (b) that some
people prefer to have comments for every method, no matter how
self-documenting it is. I don't; I prefer the source code to be as
clean as possible (though no cleaner :)


David
 
G

gwtmp01

* How to dynamically set annotations? Even with this nice looking
notation you would still need a way to do via normal methods.

How about adding methods to Class and Method?

class Sample
def foo(a1, a2); end
end

Sample.annotate:)author => "Gary Wright")

method_obj = Sample.new.method("foo")

method_obj.annotate( :comment => "this is the
comment", :annotated => Time.now )
* It's important to allow annotations for methods that do not
neccessarily exit. In this way annotations would be reusable. For
example here is what you can do with facets/annotation.rb

It seems that if you extended Class and Method as I hinted at above that
you could handle run-time annotation with no change to the language
syntax.
Reuse could be accomplished by passing hash objects around as needed.

On the other hand, if the desire is to make annotations useful as
source code
documentation (or for use by language tools that are manipulating the
*source*) then you
probably need some sort of change to the language syntax.

The problem with the facets/annotation.rb approach is that there is
no way to
statically examine the source and discover the annotations since
syntactically
the mechanism consists of standard method calls.


Gary Wright
 
A

Adam Sanderson

I think the comments example isn't a good one, but there are some other
reasons to annotate. For instance, it may be useful to annotate
objects with information about how to display them in a gui for
instance.
.adam
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,218
Latest member
JolieDenha

Latest Threads

Top