[lnkForumImage]
TotalShareware - Download Free Software

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


 

Trans

3/22/2008 1:15:00 PM

I've come across a number of occasions where methods like
#class_attr_accessor, or #module_alias_method are defined. It's nice
to have those, but it seems to me this isn't very DRY since the
methods for these things already exist in the class domain (ie.
singleton class). So what do others think of this instead:

module Kernel

# Provides access to an object's metaclass (singleton class)
# by-passing access provisions. So for example:
#
# class X
# meta.attr_accesser :a
# end
#
# X.a = 1
# X.a #=> 1

def meta
@_meta_functor ||= Functor.new do |op,*args|
(class << self; self; end).__send__(op,*args)
end
end

end

Personally, I've wished I could name the method #class and/or #module,
but obviously that's not doable. In any case, do you think this is a
better approach? Are there any serious disadvantages to it? Or do you
prefer a myriad of special class level methods? If so why?

If you are not familiar with Facets Functor, it's your basic higher
order message:

class Functor

# Privatize all methods except vital methods and #binding.
private(*instance_methods.select { |m| m !~ /(^__|^binding$)/ })

def initialize(&function)
@function = function
end

def to_proc
@function
end

# Any action against the functor is processesd by the function.
def method_missing(op, *args, &blk)
@function.call(op, *args, &blk)
end

end

Thanks,
T.

15 Answers

Robert Klemme

3/22/2008 1:39:00 PM

0

On 22.03.2008 14:15, Trans wrote:
> I've come across a number of occasions where methods like
> #class_attr_accessor, or #module_alias_method are defined. It's nice
> to have those, but it seems to me this isn't very DRY since the
> methods for these things already exist in the class domain (ie.
> singleton class). So what do others think of this instead:
>
> module Kernel
>
> # Provides access to an object's metaclass (singleton class)
> # by-passing access provisions. So for example:
> #
> # class X
> # meta.attr_accesser :a
> # end
> #
> # X.a = 1
> # X.a #=> 1
>
> def meta
> @_meta_functor ||= Functor.new do |op,*args|
> (class << self; self; end).__send__(op,*args)
> end
> end
>
> end
>
> Personally, I've wished I could name the method #class and/or #module,
> but obviously that's not doable. In any case, do you think this is a
> better approach? Are there any serious disadvantages to it? Or do you
> prefer a myriad of special class level methods? If so why?
>
> If you are not familiar with Facets Functor, it's your basic higher
> order message:
>
> class Functor
>
> # Privatize all methods except vital methods and #binding.
> private(*instance_methods.select { |m| m !~ /(^__|^binding$)/ })
>
> def initialize(&function)
> @function = function
> end
>
> def to_proc
> @function
> end
>
> # Any action against the functor is processesd by the function.
> def method_missing(op, *args, &blk)
> @function.call(op, *args, &blk)
> end
>
> end
>
> Thanks,
> T.

I am feeling stupid because I seem to overlook something: what is the
advantage of your approach vs.

class Object
def meta
class<<self;self;end
end
end

? As far as I can see your functor in this case simply delegates all
method invocations to the singleton class. Why not directly use /
return it?

While I think about it you could even do:

class Object
def meta(&b)
cl = class<<self;self;end
cl.class_eval(&b) if b
cl
end
end

class Some
meta do
attr_accessor :foo

def incr
self.foo += 1
end
end
end

Kind regards

robert

Ryan Davis

3/22/2008 5:37:00 PM

0


On Mar 22, 2008, at 06:39 , Robert Klemme wrote:
> I am feeling stupid because I seem to overlook something: what is
> the advantage of your approach vs.
>
> class Object
> def meta
> class<<self;self;end
> end
> end

Your approach mentarbates less, so trans doesn't like it as much.


Rick DeNatale

3/22/2008 6:39:00 PM

0

On 3/22/08, Ryan Davis <ryand-ruby@zenspider.com> wrote:
>
> On Mar 22, 2008, at 06:39 , Robert Klemme wrote:
> > I am feeling stupid because I seem to overlook something: what is
> > the advantage of your approach vs.
> >
> > class Object
> > def meta
> > class<<self;self;end
> > end
> > end
>
>
> Your approach mentarbates less, so trans doesn't like it as much.

Along these lines, note Stu Halloway's blog post about the definition
of Object#metaclass in facets vs. other places and the ensuing
commentary:

http://blog.thinkrelevance.com/2008/2/12/how-should-meta...

I'd seen lots of examples of metaclass being defined the same way as
Robert's proposed meta method above, and had never seen the more
complex implementation in facets until Stu bumped into problems
because use was using facets 'feature' of taking a block.

I totally agree with the consensus in the comments that the simpler
definition is better. I also side with Jim Weirich about the
distinction between metaclass and singleton class or eigenclass or
whatever you want to call them.
--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denh...

Trans

3/22/2008 7:21:00 PM

0

Hi Robert,

On Mar 22, 9:39 am, Robert Klemme <shortcut...@googlemail.com> wrote:
> I am feeling stupid because I seem to overlook something: what is the
> advantage of your approach vs.
>
> class Object
> def meta
> class<<self;self;end
> end
> end
>
> ? As far as I can see your functor in this case simply delegates all
> method invocations to the singleton class. Why not directly use /
> return it?

Try it:

>> class X
>> meta.attr_accessor
>> end
NoMethodError: private method `attr_accessor' called for #<Class:X>
from (irb):7

> While I think about it you could even do:
>
> class Object
> def meta(&b)
> cl = class<<self;self;end
> cl.class_eval(&b) if b
> cl
> end
> end
>
> class Some
> meta do
> attr_accessor :foo
>
> def incr
> self.foo += 1
> end
> end
> end

There's no need for meta at all, you could just use "class << self"
directly,

class Some
class << self
attr_accessor :foo

def incr
self.foo += 1
end
end
end

But just as some people prefer to use "def self.foo", it's nice to use
module level methods like #class_attr_accessor. That's were #meta
comes in as generalized form rather than defining class level
equivalents for all possible methods.

T.

Trans

3/22/2008 7:41:00 PM

0



On Mar 22, 2:39 pm, "Rick DeNatale" <rick.denat...@gmail.com> wrote:
> On 3/22/08, Ryan Davis <ryand-r...@zenspider.com> wrote:
>
>
>
> > On Mar 22, 2008, at 06:39 , Robert Klemme wrote:
> > > I am feeling stupid because I seem to overlook something: what is
> > > the advantage of your approach vs.
>
> > > class Object
> > > def meta
> > > class<<self;self;end
> > > end
> > > end
>
> > Your approach mentarbates less, so trans doesn't like it as much.
>
> Along these lines, note Stu Halloway's blog post about the definition
> of Object#metaclass in facets vs. other places and the ensuing
> commentary:
>
> http://blog.thinkrelevance.com/2008/2/12/how-should-meta...
>
> I'd seen lots of examples of metaclass being defined the same way as
> Robert's proposed meta method above, and had never seen the more
> complex implementation in facets until Stu bumped into problems
> because use was using facets 'feature' of taking a block.
>
> I totally agree with the consensus in the comments that the simpler
> definition is better.

Actually in Facets, #singelton_class is defined witht the simpler
definition. #meta_class is not. However, I don't agree that the
simplier case is somehow better. The issue is that Ruby will no-op a
block regardless. For example:

def x; "1"; end
x{"whatever"} #=> 1

So it has nothing per se to do with the definition of #meta_class.
It's an aspect of Ruby, and the fact that there are two definitions of
this floating around out there. So between the two, I tend toward not
wasting name space. If supporting the block takes nothing away from
the regular usage, and it reads better, then whats the issue exactly?

> I also side with Jim Weirich about the
> distinction between metaclass and singleton class or eigenclass or
> whatever you want to call them.

That's Smalltalk not Ruby. I understand the distinction people want to
draw, but in Ruby they are the same construct.

T.


Robert Dober

3/22/2008 7:54:00 PM

0

>
> That's Smalltalk not Ruby. I understand the distinction people want to
> draw, but in Ruby they are the same construct.
Thats why I think that overloading the expression "singleton class" is
somehow confusing.
Just my 2cents.
R.
>
> T.
>
>
>



--
http://ruby-smalltalk.blo...

---
Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein

Trans

3/22/2008 8:11:00 PM

0



On Mar 22, 3:53 pm, "Robert Dober" <robert.do...@gmail.com> wrote:
> > That's Smalltalk not Ruby. I understand the distinction people want to
> > draw, but in Ruby they are the same construct.
>
> Thats why I think that overloading the expression "singleton class" is
> somehow confusing.
> Just my 2cents.
> R.

I agree with that. But nothing else seems to stick. Even today I
thought of "domain class", but I'm not sure that has all the right
connotations either.

T.

Rick DeNatale

3/22/2008 10:29:00 PM

0

On 3/22/08, Trans <transfire@gmail.com> wrote:

> > I also side with Jim Weirich about the
> > distinction between metaclass and singleton class or eigenclass or
> > whatever you want to call them.
>
>
> That's Smalltalk not Ruby. I understand the distinction people want to
> draw, but in Ruby they are the same construct.

I respectfully disgree.

Singleton classes in Ruby are an implementation construct which is
used for two distinct purposes:

1) To provide a place to put instance behavior. For example

a = "abc"
def a.foo
:foo
end

2) To provide a class for a class, i.e. a metaclass.

One difference is that the first can't have subclasses, while
singleton classes used as metaclasses can and must since the
inheritance chain of metaclasses parallels the inheritance chain of
their instances. The otehr is that metaclasses is the class of a
class, not an arbitrary object. For all practical purposes, the second
kind acts exactly as metaclasses do in Smalltalk, and Matz was quoted
as such in the 2nd ed of the Pickaxe. Unfortunately many in the Ruby
community misunderstood that page as equating metaclass with singleton
class rather than seeing that although singleton classes are used to
implement metaclasses in Ruby, all singleton classes are NOT
metaclasses, a term which has a meaning even beyond Smalltalk of being
the class of a class.

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denh...

Sean O'Halpin

3/22/2008 11:14:00 PM

0

On Sat, Mar 22, 2008 at 1:39 PM, Robert Klemme
<shortcutter@googlemail.com> wrote:
> While I think about it you could even do:
>
> class Object
> def meta(&b)
> cl = class<<self;self;end
> cl.class_eval(&b) if b
> cl
> end
> end
>
> class Some
> meta do
> attr_accessor :foo
>
> def incr
> self.foo += 1
> end
> end
> end
>
> Kind regards
>
> robert
>

Indeed - I'm using almost identical code in doodle[1] but using the
name #singleton_class instead of #meta :)

def singleton_class(&block)
sc = (class << self; self; end)
sc.module_eval(&block) if block_given?
sc
end

@Trans - doesn't #meta clash with an openuri attribute? I've just
removed it as an alias to #singleton_class in doodle for that reason.
FWIW, I'm considering renaming #singleton_class to avoid clashing with
someone else's definition. Perhaps, something like
#the_method_formerly_and_variously_known_as_singleton_eigen_or_meta_class
;)

Regards,
Sean

[1] http://doodle.rub...

Robert Klemme

3/23/2008 11:17:00 AM

0

On 22.03.2008 20:21, Trans wrote:
> On Mar 22, 9:39 am, Robert Klemme <shortcut...@googlemail.com> wrote:
>> I am feeling stupid because I seem to overlook something: what is the
>> advantage of your approach vs.
>>
>> class Object
>> def meta
>> class<<self;self;end
>> end
>> end
>>
>> ? As far as I can see your functor in this case simply delegates all
>> method invocations to the singleton class. Why not directly use /
>> return it?
>
> Try it:
>
>>> class X
>>> meta.attr_accessor
>>> end
> NoMethodError: private method `attr_accessor' called for #<Class:X>
> from (irb):7

So then the only (?) advantage of your proposal is that you can use
private methods like ordinary methods.

> There's no need for meta at all, you could just use "class << self"
> directly,

True enough. And "class << self ... end" is not as ugly as "class
<<self;self;end" for getting at the instance itself.

> But just as some people prefer to use "def self.foo", it's nice to use
> module level methods like #class_attr_accessor. That's were #meta
> comes in as generalized form rather than defining class level
> equivalents for all possible methods.

I see. Thanks for the enlightenment.

Kind regards

robert