[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

mixing in class methods

Mark J. Reed

10/1/2003 8:47:00 PM

Okay, probably a dumb question, but: is there any way to define
methods in a module which become class methods of any class which
includes that module?

For instance:

module Foo;
class << self
def foo; puts "foo!"; end
end
end

class Bar
include Foo
end

Bar.foo

NoMethodError: undefined method `foo' for Bar:Class
from (irb):11


-Mark
6 Answers

Ryan Pavlik

10/1/2003 9:08:00 PM

0

On Thu, 2 Oct 2003 06:02:32 +0900
"Mark J. Reed" <markjreed@mail.com> wrote:

> Okay, probably a dumb question, but: is there any way to define
> methods in a module which become class methods of any class which
> includes that module?

Close:

module M
def foo
p "Hello world"
end
end

class C
end

class << C
include M
end

C.foo # => "Hello world"

hth,

--
Ryan Pavlik <rpav@mephle.com>

"I've got a crude stabbing implement right here with
your name all over it." - 8BT

Gavin Sinclair

10/1/2003 10:37:00 PM

0

On Thursday, October 2, 2003, 7:08:00 AM, Ryan wrote:

> On Thu, 2 Oct 2003 06:02:32 +0900
> "Mark J. Reed" <markjreed@mail.com> wrote:

>> Okay, probably a dumb question, but: is there any way to define
>> methods in a module which become class methods of any class which
>> includes that module?

> Close:

> module M
> def foo
> p "Hello world"
> end
> end

> class C
> end

> class << C
> include M
> end

> C.foo # => "Hello world"


Alternatively,

class C
extend M
end

C.foo # => "Hello world"

Gavin


Mark J. Reed

10/2/2003 12:41:00 AM

0

On Thu, Oct 02, 2003 at 07:37:25AM +0900, Gavin Sinclair wrote:
> On Thursday, October 2, 2003, 7:08:00 AM, Ryan wrote:
>
> > class << C
> > include M
> > end
>
> Alternatively,
>
> class C
> extend M
> end

Okay, those both work, assuming all I want is class methods from the module.
I'm guessing I have to break it up. The original idea was to have a
single module, which defined both class and instance methods, which I could
include/extend/whatever into a class, and then that class would have both
the instance methods (as instance methods) and the class methods (as
class methods) from the module.

-Mark

Gavin Sinclair

10/2/2003 1:40:00 AM

0

> On Thu, Oct 02, 2003 at 07:37:25AM +0900, Gavin Sinclair wrote:
>> On Thursday, October 2, 2003, 7:08:00 AM, Ryan wrote:
>>
>> > class << C
>> > include M
>> > end
>>
>> Alternatively,
>>
>> class C
>> extend M
>> end
>
> Okay, those both work, assuming all I want is class methods from the
> module. I'm guessing I have to break it up. The original idea was to
> have a single module, which defined both class and instance methods,
> which I could include/extend/whatever into a class, and then that class
> would have both the instance methods (as instance methods) and the class
> methods (as class methods) from the module.
>
> -Mark

Yes, it's too much to ask :) Ruby doesn't know the difference between
instance and class methods. Every method is an instance method, it's just
that some instances happen to be classes.

Note that "C.extend(M)" works as well, just like "(s = '').extend(M)".

It sometimes makes me wonder why Ruby differentiates between instance
variables and class variables. The latter seem exceptional, for a number
of reasons.

Gavin




ahoward

10/2/2003 2:58:00 AM

0

Gavin Sinclair

10/2/2003 5:33:00 AM

0







<387038350.20031002083705@soyabean.com.au>
<20031002004040.GA28752@mulan.thereeds.org>
<63889.203.185.214.34.1065055366.squirrel@webmail.imagineis.com>
<Pine.LNX.4.53.0310020257280.8983@eli.fsl.noaa.gov>
X-ML-Name: ruby-talk
X-Mail-Count: 83420
X-MLServer: fml [fml 4.0.3 release (20011202/4.0.3)]; post only (anyone can post)
X-ML-Info: If you have a question, send e-mail with the body
"help" (without quotes) to the address ruby-talk-ctl@ruby-lang.org;
help=<mailto:ruby-talk-ctl@ruby-lang.org?body=help>
X-Mailer: SquirrelMail (version 1.2.7)
X-Priority: 3
Importance: Normal
X-MSMail-Priority: Normal
Mime-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit
Precedence: bulk
Lines: 87
List-Id: ruby-talk.ruby-lang.org
List-Software: fml [fml 4.0.3 release (20011202/4.0.3)]
List-Post: <mailto:ruby-talk@ruby-lang.org>
List-Owner: <mailto:ruby-talk-admin@ruby-lang.org>
List-Help: <mailto:ruby-talk-ctl@ruby-lang.org?body=help>
List-Unsubscribe: <mailto:ruby-talk-ctl@ruby-lang.org?body=unsubscribe>
X-Spam-Status: No, hits=-5.2 required=5.0
tests=AWL,BAYES_01,IN_REP_TO,MISSING_MIMEOLE,
MISSING_OUTLOOK_NAME,QUOTED_EMAIL_TEXT,REFERENCES,
REPLY_WITH_QUOTES
version=2.55
X-Spam-Level:
X-Spam-Checker-Version: SpamAssassin 2.55 (1.174.2.19-2003-05-19-exp)

>> It sometimes makes me wonder why Ruby differentiates between instance
>> variables and class variables. The latter seem exceptional, for a
>> number of reasons.
>
> [Ara:]
>
> ~/eg/ruby > cat classvar.rb
> class A
> @@a = 42 # i am a class var, and can be inherited
> @a = 42 # i belong to THIS instance of a class, class A
> end
>
> class B < A
> printf "@@a = <%s>\n", (@@a or 'nil')
> printf "@a = <%s>\n", (@a or 'nil')
> end
>
> ~/eg/ruby > ruby classvar.rb
> @@a = <42>
> @a = <nil>

Yeah, I know the theory (but thanks for summarising anyway), but I haven't
comfortably fit it in to my programming arsenal. e.g. recently I had some
code like this.

class Project
@@implemented_methods = []

def implement(_method)
# some checking
yield
# some checking
@@implemented_methods << _method
end

def Project.implemented_methods
@@implemented_methods
end
end

So, what do I consider "exceptional"? Some comments:

1. Accessing a class variable is nowhere near as convenient as
accessing an instance variable.

2. "class methods" and "instance methods" are the same concept
(since classes are objects), but there's nothing to unify
"class variables" and "instance variables". Observe that

a) class variables (@@example) can be resolved whether "self"
represents the class or the instance

b) "class methods", unlike in Java (static methods), can't be
directly accessed from the instance

3. Although "class instance variables" are a logical entity,
they do not appear to be a common programming idiom.

I initially tried to code my example like this:

class Project
class << Project
attr_accessor :implemented_methods
end

def implement(_method)
# some checking
yield
# some checking
Project.implemented_methods << _method
end
end

Note in both examples, the idea is to be able to call

Project.implemented_methods

after calling Project#implement a number of times. However, the second
case (using a class instance variable instead of a class variable) did not
work. I think the array always came back empty. Now I may have done
something simple wrong, but I think I've demonstrated enough anyway. :)
Well, I hope so.

Cheers,
Gavin