[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Trans

1/24/2005 1:50:00 PM

In the upcoming release of Ruby Carats I have a little lib called
attr.rb.

What it does is define a mater #define_attribute which all attribute
defintions are routed thru. Then I redefine #attr (since current
definition is basically never used) to call #define_attribute that
takes multiple args. Here's an example:

.. attr :a, :a=

which is equivalent to:

.. attr_reader :a
.. attr_writer :a

It also has some extra freatures that are nice like:

.. attr :a?, :b!

which is the same as

.. def a?
.. @a ? true : @a
.. end
.
.. def b!(x)
.. @b.replace x
.. end

Also these return an array of the symbols of the methods that get
defined, so you can use public, private, protected on them. eg.

.. private attr :a

There are a couple of other features too, but I'll leave those aside
for now, as they are not important to this inquery.

So I have a few questions. First, what do you think of this in general?
Second, there is no "extra" convenient way to do an accessor b/c I
haven't been able to find a nice notation --one just has to put both,
'attr :a, :a='. Is this too inconvenient? Can anyone think of a good
notation?

Thanks,
T.

37 Answers

Jamis Buck

1/24/2005 2:12:00 PM

0

On 22:51 Mon 24 Jan , Trans wrote:
> In the upcoming release of Ruby Carats I have a little lib called
> attr.rb.
>
> What it does is define a mater #define_attribute which all attribute
> defintions are routed thru. Then I redefine #attr (since current
> definition is basically never used) to call #define_attribute that

Well.... claiming that it is "basically never used" is dangerous. I've
used it, and I know I've seen code that uses it. Changing the
semantics of an existing method is always going to be dangerous, no
matter how infrequently you believe the method is used in practice.

Caution, caution, caution. :)

> So I have a few questions. First, what do you think of this in general?
> Second, there is no "extra" convenient way to do an accessor b/c I
> haven't been able to find a nice notation --one just has to put both,
> 'attr :a, :a='. Is this too inconvenient? Can anyone think of a good
> notation?

I like the features you've added, though. Could you perhaps call it
something other than "attr", to avoid breakage?

- Jamis

--
Jamis Buck
jamis_buck@byu.edu
http://jamis.jam...
------------------------------
"I am Victor of Borge. You will be assimil-nine-ed."



Trans

1/24/2005 2:39:00 PM

0

> I like the features you've added, though.
> Could you perhaps call it something other than
> "attr", to avoid breakage?

I suppose, but first let me explain. It used to be called #def_attr for
the reason you state. But I always felt like I might as well use #attr
due to its _relative_ uselessness (i.e. overlap functionality with much
more commonly used methods). So I posted a topic here on this list
(110245) that asked about it, and the jist seemed to be that it was
pretty much abandoned. Also, keep in mind that programs using the old
#attr won't be effected unless they become a part of something that
requires this lib --and hell, the current definition of #attr almost
seems like a bug anyway; maybe poeple be happy to finally root them
out. Further, it is backward compatible with reader notation; just not
the accessor notation (i.e. 'attr :a, true').

Oh I forgot a question too. Sould 'attr :a=' create just a writer, like
I have it, or should it instead create a reader and a writer, since
writers are very uncommon? (Though in that case I don't know what
notation to use for just writer.)

-T.

Robert Klemme

1/24/2005 4:25:00 PM

0


"Trans" <transfire@gmail.com> schrieb im Newsbeitrag
news:1106574588.198173.83840@f14g2000cwb.googlegroups.com...
> In the upcoming release of Ruby Carats I have a little lib called
> attr.rb.
>
> What it does is define a mater #define_attribute which all attribute
> defintions are routed thru. Then I redefine #attr (since current
> definition is basically never used) to call #define_attribute that
> takes multiple args. Here's an example:
>
> . attr :a, :a=
>
> which is equivalent to:
>
> . attr_reader :a
> . attr_writer :a
>
> It also has some extra freatures that are nice like:
>
> . attr :a?, :b!
>
> which is the same as
>
> . def a?
> . @a ? true : @a
> . end

Why not "def a?() @a end"?

> . def b!(x)
> . @b.replace x
> . end

Hm, I don't like that because it's too special case. Also you might want
to be able to assign and to replace...

> Also these return an array of the symbols of the methods that get
> defined, so you can use public, private, protected on them. eg.
>
> . private attr :a
>
> There are a couple of other features too, but I'll leave those aside
> for now, as they are not important to this inquery.
>
> So I have a few questions. First, what do you think of this in general?
> Second, there is no "extra" convenient way to do an accessor b/c I
> haven't been able to find a nice notation --one just has to put both,
> 'attr :a, :a='. Is this too inconvenient? Can anyone think of a good
> notation?

Although I find "attr_accessor" quite lengthy, I don't really see the
benefit of your proposal. And attr_accessor does indeed define reader and
writer for several attributes...

Kind regards

robert

Trans

1/24/2005 4:51:00 PM

0

>> . def a?
>> . @a ? true : @a
>> . end

> Why not "def a?() @a end"?

Becasue that would be the exact same as 'attr :a'. What would be the
point? This guaruntees only three possible return values: true, false,
and nil.

>> . def b!(x)
>> . @b.replace x
>> . end

> Hm, I don't like that because it's too special case.

Well, these _are_ special cases. Don't see any reason not to like them
b/c of that. Just dont use them. Since the "functional space" is simply
going unused anyway (i.e. symbols can end in ? and ! without quoting),
and it coorepsonds to certain forms of method definitions, I gave them
the most reasonble base-line usage I could think of.

> Also you might want to be able to assign and to replace...

I think you'd just replace first from the calling routine, and then
assign. Or perhaps I misunderstand?

> Although I find "attr_accessor" quite lengthy, I don't
> really see the benefit of your proposal. And attr_accessor
> does indeed define reader and writer for several attributes

Ah, but there are many advantages, not just the fact that attr is
shorter. You can define both readers and writers in the same call. The
names of the methods defined are returned so you can use public,
private, protected (and user defined methods too!) in front of them.
They also route through a common #define_attribute method, so there is
central control, and it stores all defined attribute methods so you can
ask for a list of them. It also has casting, somthing I came up with a
few years ago. Eg.
.. attr :a => :to_s

which defines

.. def a
.. @a.to_s
.. end

~T.

Jeffrey Moss

1/24/2005 5:26:00 PM

0

You know, this is commonly called "aspect oriented programming" if I am not
mistaken. You may want to look into it. I didn't find this paradigm very
easy to think in, but there are people out there who swear by it, so maybe
you should head in that direction and name the library accordingly.

I did a quick google search for aspect oriented programming ruby and found
some stuff out there that's already done. (http://aspec...)

-Jeff

>> In the upcoming release of Ruby Carats I have a little lib called
>> attr.rb.
>>
>> What it does is define a mater #define_attribute which all attribute
>> defintions are routed thru. Then I redefine #attr (since current
>> definition is basically never used) to call #define_attribute that
>
> Well.... claiming that it is "basically never used" is dangerous. I've
> used it, and I know I've seen code that uses it. Changing the
> semantics of an existing method is always going to be dangerous, no
> matter how infrequently you believe the method is used in practice.
>
> Caution, caution, caution. :)
>
>> So I have a few questions. First, what do you think of this in general?
>> Second, there is no "extra" convenient way to do an accessor b/c I
>> haven't been able to find a nice notation --one just has to put both,
>> 'attr :a, :a='. Is this too inconvenient? Can anyone think of a good
>> notation?
>
> I like the features you've added, though. Could you perhaps call it
> something other than "attr", to avoid breakage?
>
> - Jamis
>
> --
> Jamis Buck
> jamis_buck@byu.edu
> http://jamis.jam...
> ------------------------------
> "I am Victor of Borge. You will be assimil-nine-ed."
>
>



Glenn Parker

1/24/2005 6:58:00 PM

0

Trans wrote:
>
> So I have a few questions. First, what do you think of this in general?

Clever stuff for golfing, and possibly useful as a way to illustrate the
meta-programming flexibility of Ruby, but it adds nothing meaningful
while moderately obfuscating some simple tasks. You've come up with a
way to compress two or three lines of trivially understood Ruby down to
one line of obscure Ruby. To me, the original two or three "verbose"
lines are preferable because they are more easily recognized and
understood by a Ruby coder.

--
Glenn Parker | glenn.parker-AT-comcast.net | <http://www.tetrafoi...


Robert Klemme

1/24/2005 7:01:00 PM

0


"Trans" <transfire@gmail.com> schrieb im Newsbeitrag
news:1106585454.733119.216360@z14g2000cwz.googlegroups.com...
>>> . def a?
>>> . @a ? true : @a
>>> . end
>
>> Why not "def a?() @a end"?
>
> Becasue that would be the exact same as 'attr :a'. What would be the
> point? This guaruntees only three possible return values: true, false,
> and nil.

So you want to protect the real value. Is that the reasoning behind this?

>>> . def b!(x)
>>> . @b.replace x
>>> . end
>
>> Hm, I don't like that because it's too special case.
>
> Well, these _are_ special cases. Don't see any reason not to like them
> b/c of that. Just dont use them. Since the "functional space" is simply
> going unused anyway (i.e. symbols can end in ? and ! without quoting),
> and it coorepsonds to certain forms of method definitions, I gave them
> the most reasonble base-line usage I could think of.

Still you introduce a method in class Module that has some special behavior
which at least clutters namespace - even if unused. As Module is a very
basic class it's behavior should be most general, too - my 0.02 EUR. (You
can always define an add on that adds these methods.)

>> Also you might want to be able to assign and to replace...
>
> I think you'd just replace first from the calling routine, and then
> assign. Or perhaps I misunderstand?

I meant that with only the replace version of the method there is no option
to assign to the member var. But with the getter you can already replace.
Of course, a.c! "foo" is shorter than a.c.replace "foo" - but then again,
it's a special case as it applies only to String (or at least mostly). :-)

>> Although I find "attr_accessor" quite lengthy, I don't
>> really see the benefit of your proposal. And attr_accessor
>> does indeed define reader and writer for several attributes
>
> Ah, but there are many advantages, not just the fact that attr is
> shorter. You can define both readers and writers in the same call.

I can do that with attr_accessor.

> The
> names of the methods defined are returned so you can use public,
> private, protected (and user defined methods too!) in front of them.

This works only if the method returns a single symbol. Otherwise it's going
to be ugly:

class Module
def a(*x) :single end
def b(*x) [:a,:b] end
end

class Foo
def single; end
def a;end
def b;end

private a :a, :b
private b :c, :d # doesn't work
private *b :c, :d # doesn't work
private *b( :c, :d) # ugly
end

> They also route through a common #define_attribute method, so there is
> central control, and it stores all defined attribute methods so you can
> ask for a list of them. It also has casting, somthing I came up with a
> few years ago. Eg.
> . attr :a => :to_s
>
> which defines
>
> . def a
> . @a.to_s
> . end

Interesting.

I'm sorry that I don't share your enthusiasm - I simply don't miss this
functionality.

Regards

robert

Trans

1/24/2005 7:53:00 PM

0


Robert Klemme wrote:
> So you want to protect the real value. Is that the reasoning behind
this?

Not exactly. It is simply one readibility really and overlapping
functionality. For instance if you saw:

| case a?

What would you expect to be in the when clauses? It's customary to
expect a mthod ending in ? to return a "boolean" (true, false, nil).
You wouldn;t expect to see something like:

| a?.kind_of(Integer)

That's not to say you can't do it if you want, but is atypical. You
would just use 'a.kind_of(Integer)'.

> Still you introduce a method in class Module that has some special
behavior
> which at least clutters namespace - even if unused. As Module is a
very
> basic class it's behavior should be most general, too - my 0.02 EUR.

I don;t see how it clutters namespace. It's one method. The special
behavior is quite basic, so I don't see how that's really get in the
way. But I guess that's my 2 cents too.

> (You can always define an add on that adds these methods.)

Isn't that what I'm doing?

> >> Also you might want to be able to assign and to replace...
> >
> > I think you'd just replace first from the calling routine, and then
> > assign. Or perhaps I misunderstand?
>
> I meant that with only the replace version of the method there is no
option
> to assign to the member var. But with the getter you can already
replace.
> Of course, a.c! "foo" is shorter than a.c.replace "foo" - but then
again,
> it's a special case as it applies only to String (or at least
mostly). :-)

Sure. I don't think the ! notaiton will be of great use. But niether is
the current definition of #attr. I just gave it something to do that's
simple and straigh foward that goes along with the gernal meaning of !
on the end of a method. But perhaps you have better use for the
notation?

> > Ah, but there are many advantages, not just the fact that attr is
> > shorter. You can define both readers and writers in the same call.
>
> I can do that with attr_accessor.

No becasue you get both a reader and a writer for each. What I mean is:

attr :a, :b=

Is one reader and one writer.

> > The
> > names of the methods defined are returned so you can use public,
> > private, protected (and user defined methods too!) in front of
them.
>
> This works only if the method returns a single symbol. Otherwise
it's going
> to be ugly:
>
> class Module
> def a(*x) :single end
> def b(*x) [:a,:b] end
> end
>
> class Foo
> def single; end
> def a;end
> def b;end
>
> private a :a, :b
> private b :c, :d # doesn't work
> private *b :c, :d # doesn't work
> private *b( :c, :d) # ugly
> end

Yes, that's something I have a distate for in Ruby --that there's no
way to pass through arguments-per-arguments via return. I.e.

| def self.b(*x) ; return *x ; end
| private b

#b still returns an array with or without the * in 'return *x', it
seems. But there is of course the solution of altering public, private
and protected to accept an array.

> > They also route through a common #define_attribute method, so there
is
> > central control, and it stores all defined attribute methods so you
can
> > ask for a list of them. It also has casting, somthing I came up
with a
> > few years ago. Eg.
> > . attr :a => :to_s
> >
> > which defines
> >
> > . def a
> > . @a.to_s
> > . end
>
> Interesting.
>
> I'm sorry that I don't share your enthusiasm - I simply don't miss
this
> functionality.

Why would you miss it? You have never had it :) I have been using for
awhile now. Most of the time it's of small consequence. But every once
in a while these extra "touches" come in quite handy.

T.

Trans

1/24/2005 7:58:00 PM

0

Thanks Glenn,

But do you really find something like:

| attr :a, :a=, :c?

so obfuscating? Every thing has some learning curve to it. I grant you.
But my bet is that this notation would be almost completely undestood
on one's first hunch.

T.

Trans

1/24/2005 8:04:00 PM

0

Hi Jeffery,

I wouldn't exaclty call it AOP, although I can understand some analogy
here.

If you'd like to see some extensive work on the subject of Ruby and AOP
have a look at the RcrFoundy on the Ruby Garden Wiki. It's also a
common topic at on the suby-ruby mailing list.

Thanks,
-T.