[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Mixin questions

Johan Nilsson

12/14/2004 10:06:00 AM

Hi,

some newbie questions:

- How can/should I access a class constant from a mixin? The only thing I've
managed to get working is "const_get("name of const")".
- Is it possible to access protected methods from mixins? I'm trying to
create a mixin alike the following:

---
module StaticCreateMixin
def create_from(stuff)
obj = self.new
obj.my_stuff.<modifiying fn>!(stuff)
obj
end
end

class Foo
extend StaticCreateMixin

def my_stuff
@stuff
end

protected :my_stuff
end

f = Foo.static_create("some stuff")

---

(no, I can't pass the "some stuff" as parameter to Foo.initialize)

Thanks // Johan

10 Answers

Robert Klemme

12/14/2004 10:42:00 AM

0


"Johan Nilsson" <johan.nilsson@---.esrange.ssc.se> schrieb im Newsbeitrag
news:1103018684.0021a1444d2417eb0d9c6eddf9e60f0d@teranews...
> Hi,
>
> some newbie questions:
>
> - How can/should I access a class constant from a mixin? The only thing
I've
> managed to get working is "const_get("name of const")".
> - Is it possible to access protected methods from mixins? I'm trying to
> create a mixin alike the following:
>
> ---
> module StaticCreateMixin
> def create_from(stuff)
> obj = self.new
> obj.my_stuff.<modifiying fn>!(stuff)
> obj
> end
> end
>
> class Foo
> extend StaticCreateMixin
>
> def my_stuff
> @stuff
> end
>
> protected :my_stuff
> end
>
> f = Foo.static_create("some stuff")

Your example misses something, does it? It's not completely clear to me
what you want to do. Or did you misspell create_from as static_create?

Kind regards

robert

Johan Nilsson

12/14/2004 12:51:00 PM

0


"Robert Klemme" <bob.news@gmx.net> wrote in message
news:327uc2F3j9j3eU1@individual.net...
>
> "Johan Nilsson" <johan.nilsson@---.esrange.ssc.se> schrieb im Newsbeitrag
> news:1103018684.0021a1444d2417eb0d9c6eddf9e60f0d@teranews...
> > Hi,
> >
> > some newbie questions:
> >
> > - How can/should I access a class constant from a mixin? The only thing
> I've
> > managed to get working is "const_get("name of const")".
> > - Is it possible to access protected methods from mixins? I'm trying to
> > create a mixin alike the following:
> >
> > ---
> > module StaticCreateMixin
> > def create_from(stuff)
> > obj = self.new
> > obj.my_stuff.<modifiying fn>!(stuff)
> > obj
> > end
> > end
> >
> > class Foo
> > extend StaticCreateMixin
> >
> > def my_stuff
> > @stuff
> > end
> >
> > protected :my_stuff
> > end
> >
> > f = Foo.static_create("some stuff")
>
> Your example misses something, does it? It's not completely clear to me
> what you want to do. Or did you misspell create_from as static_create?

Oops. Yes, I'm a very bad speller (or it could be the
"extract-a-minimal-sample-from-actual-code-but-don't-bother-to-test-it"-synd
rome).

In english, I want to create an instance of Foo from within the mixin's
supplied class method. The first question still applies though.

// Johan

Robert Klemme

12/14/2004 1:08:00 PM

0


"Johan Nilsson" <johan.nilsson@---.esrange.ssc.se> schrieb im Newsbeitrag
news:1103028594.879ec90c8d4eeda7699d84d52c2d5a65@teranews...
>
> "Robert Klemme" <bob.news@gmx.net> wrote in message
> news:327uc2F3j9j3eU1@individual.net...
> >
> > "Johan Nilsson" <johan.nilsson@---.esrange.ssc.se> schrieb im
Newsbeitrag
> > news:1103018684.0021a1444d2417eb0d9c6eddf9e60f0d@teranews...
> > > Hi,
> > >
> > > some newbie questions:
> > >
> > > - How can/should I access a class constant from a mixin? The only
thing
> > I've
> > > managed to get working is "const_get("name of const")".
> > > - Is it possible to access protected methods from mixins? I'm trying
to
> > > create a mixin alike the following:
> > >
> > > ---
> > > module StaticCreateMixin
> > > def create_from(stuff)
> > > obj = self.new
> > > obj.my_stuff.<modifiying fn>!(stuff)
> > > obj
> > > end
> > > end
> > >
> > > class Foo
> > > extend StaticCreateMixin
> > >
> > > def my_stuff
> > > @stuff
> > > end
> > >
> > > protected :my_stuff
> > > end
> > >
> > > f = Foo.static_create("some stuff")
> >
> > Your example misses something, does it? It's not completely clear to
me
> > what you want to do. Or did you misspell create_from as
static_create?
>
> Oops. Yes, I'm a very bad speller (or it could be the
>
"extract-a-minimal-sample-from-actual-code-but-don't-bother-to-test-it"-sy
nd
> rome).

You don't necessarily need a class method. You can make it a method in
Kernel, too:

module Kernel
private
def static_create(cl, stuff)
o = cl.new
o.my_stuff.duh! stuff
o
end
end

f = static_create( Foo, "some stuff")

Somehow I feel that a mixin might be a bit over the top - unless of course
the mixin contains more code.

> In english, I want to create an instance of Foo from within the mixin's
> supplied class method. The first question still applies though.

You mean like this?

module Mix
def test_it
p self::FOO
end
end

class Test
extend Mix
FOO = "bar"
end

irb(main):034:0* Test.test_it
"bar"
=> nil

Kind regards

robert

Johan Nilsson

12/14/2004 1:50:00 PM

0


"Robert Klemme" <bob.news@gmx.net> wrote in message
news:3286taF3it29pU1@individual.net...
>

[snip]

>
> You don't necessarily need a class method. You can make it a method in
> Kernel, too:
>
> module Kernel
> private
> def static_create(cl, stuff)
> o = cl.new
> o.my_stuff.duh! stuff
> o
> end
> end
>
> f = static_create( Foo, "some stuff")
>
> Somehow I feel that a mixin might be a bit over the top - unless of course
> the mixin contains more code.

Might be. Still I'd prefer:

f = Foo.static_create("some stuff")

I still don't see how the mixin can get to the protected methods though - I
get "NoMethodError: protected method 'my_stuff' called for ..." if I try
somehing like my original code.

>
> > In english, I want to create an instance of Foo from within the mixin's
> > supplied class method. The first question still applies though.
>
> You mean like this?
>
> module Mix
> def test_it
> p self::FOO
> end
> end
>
> class Test
> extend Mix
> FOO = "bar"
> end

Yes, but in my (unfortunately) more complex case I get "dynamic constant
assignment" whenever I add "self::<constant>" to the mixin (reported from
the point where the class constant is defined). Using
....self.class.const_get("<constant>") works fine though in the mixin.

The code is a bit too much to post though, if I can reduce it I'll try and
post the actual failing code instead.

// Johan

Robert Klemme

12/14/2004 3:12:00 PM

0


"Johan Nilsson" <johan.nilsson@---.esrange.ssc.se> schrieb im Newsbeitrag
news:1103032112.3aa9129fd718fc17e4d9eb2e027a3e52@teranews...
>
> "Robert Klemme" <bob.news@gmx.net> wrote in message
> news:3286taF3it29pU1@individual.net...
> >
>
> [snip]
>
> >
> > You don't necessarily need a class method. You can make it a method
in
> > Kernel, too:
> >
> > module Kernel
> > private
> > def static_create(cl, stuff)
> > o = cl.new
> > o.my_stuff.duh! stuff
> > o
> > end
> > end
> >
> > f = static_create( Foo, "some stuff")
> >
> > Somehow I feel that a mixin might be a bit over the top - unless of
course
> > the mixin contains more code.
>
> Might be. Still I'd prefer:
>
> f = Foo.static_create("some stuff")
>
> I still don't see how the mixin can get to the protected methods
though - I
> get "NoMethodError: protected method 'my_stuff' called for ..." if I try
> somehing like my original code.

I haven't a solution for this yet. I tried with instance_eval but to no
avail. Maybe send works. Did you try that?

> > > In english, I want to create an instance of Foo from within the
mixin's
> > > supplied class method. The first question still applies though.
> >
> > You mean like this?
> >
> > module Mix
> > def test_it
> > p self::FOO
> > end
> > end
> >
> > class Test
> > extend Mix
> > FOO = "bar"
> > end
>
> Yes, but in my (unfortunately) more complex case I get "dynamic constant
> assignment" whenever I add "self::<constant>" to the mixin (reported
from
> the point where the class constant is defined).

But then you're assigning the constant more than once. From your example
I though you just wanted to access (= read) it. Which Ruby version are
you using?

> Using
> ...self.class.const_get("<constant>") works fine though in the mixin.

Strange.

> The code is a bit too much to post though, if I can reduce it I'll try
and
> post the actual failing code instead.

Yeah, it would be good to see the real source of the problem. At the
moment I feel a bit tapping in the dark. :-)

Kind regards + good luck

robert

Kent Sibilev

12/14/2004 3:30:00 PM

0

By including a mixin module into a class you can add only instance
methods unless you implement Module#append_features(or
Module#included), if that's what you want to know.

Cheers,
Kent.

On Dec 14, 2004, at 7:52 AM, Johan Nilsson wrote:

>
> "Robert Klemme" <bob.news@gmx.net> wrote in message
> news:327uc2F3j9j3eU1@individual.net...
>>
>> "Johan Nilsson" <johan.nilsson@---.esrange.ssc.se> schrieb im
>> Newsbeitrag
>> news:1103018684.0021a1444d2417eb0d9c6eddf9e60f0d@teranews...
>>> Hi,
>>>
>>> some newbie questions:
>>>
>>> - How can/should I access a class constant from a mixin? The only
>>> thing
>> I've
>>> managed to get working is "const_get("name of const")".
>>> - Is it possible to access protected methods from mixins? I'm trying
>>> to
>>> create a mixin alike the following:
>>>
>>> ---
>>> module StaticCreateMixin
>>> def create_from(stuff)
>>> obj = self.new
>>> obj.my_stuff.<modifiying fn>!(stuff)
>>> obj
>>> end
>>> end
>>>
>>> class Foo
>>> extend StaticCreateMixin
>>>
>>> def my_stuff
>>> @stuff
>>> end
>>>
>>> protected :my_stuff
>>> end
>>>
>>> f = Foo.static_create("some stuff")
>>
>> Your example misses something, does it? It's not completely clear to
>> me
>> what you want to do. Or did you misspell create_from as
>> static_create?
>
> Oops. Yes, I'm a very bad speller (or it could be the
> "extract-a-minimal-sample-from-actual-code-but-don't-bother-to-test-
> it"-synd
> rome).
>
> In english, I want to create an instance of Foo from within the mixin's
> supplied class method. The first question still applies though.
>
> // Johan
>
>



Robert Klemme

12/14/2004 3:37:00 PM

0


"Kent Sibilev" <ksibilev@bellsouth.net> schrieb im Newsbeitrag
news:07703F80-4DE5-11D9-B79B-000A95C700E8@bellsouth.net...
> By including a mixin module into a class you can add only instance
> methods unless you implement Module#append_features(or
> Module#included), if that's what you want to know.

No. Note the fine difference between include and extend (see code below).
But anyway thanks for calling.

Also, with a little magic you can add class and instance methods either
way (i.e. with include and extend).

Kind regards

robert


> Cheers,
> Kent.
>
> On Dec 14, 2004, at 7:52 AM, Johan Nilsson wrote:
>
> >
> > "Robert Klemme" <bob.news@gmx.net> wrote in message
> > news:327uc2F3j9j3eU1@individual.net...
> >>
> >> "Johan Nilsson" <johan.nilsson@---.esrange.ssc.se> schrieb im
> >> Newsbeitrag
> >> news:1103018684.0021a1444d2417eb0d9c6eddf9e60f0d@teranews...
> >>> Hi,
> >>>
> >>> some newbie questions:
> >>>
> >>> - How can/should I access a class constant from a mixin? The only
> >>> thing
> >> I've
> >>> managed to get working is "const_get("name of const")".
> >>> - Is it possible to access protected methods from mixins? I'm trying
> >>> to
> >>> create a mixin alike the following:
> >>>
> >>> ---
> >>> module StaticCreateMixin
> >>> def create_from(stuff)
> >>> obj = self.new
> >>> obj.my_stuff.<modifiying fn>!(stuff)
> >>> obj
> >>> end
> >>> end
> >>>
> >>> class Foo
> >>> extend StaticCreateMixin
> >>>
> >>> def my_stuff
> >>> @stuff
> >>> end
> >>>
> >>> protected :my_stuff
> >>> end
> >>>
> >>> f = Foo.static_create("some stuff")
> >>
> >> Your example misses something, does it? It's not completely clear to
> >> me
> >> what you want to do. Or did you misspell create_from as
> >> static_create?
> >
> > Oops. Yes, I'm a very bad speller (or it could be the
> > "extract-a-minimal-sample-from-actual-code-but-don't-bother-to-test-
> > it"-synd
> > rome).
> >
> > In english, I want to create an instance of Foo from within the
mixin's
> > supplied class method. The first question still applies though.
> >
> > // Johan
> >
> >
>
>
>

Kent Sibilev

12/14/2004 4:30:00 PM

0

Oh, I didn't notice 'extend' in the code. Sorry about the noise.

Cheers,
Kent.
On Dec 14, 2004, at 10:37 AM, Robert Klemme wrote:

>
> "Kent Sibilev" <ksibilev@bellsouth.net> schrieb im Newsbeitrag
> news:07703F80-4DE5-11D9-B79B-000A95C700E8@bellsouth.net...
>> By including a mixin module into a class you can add only instance
>> methods unless you implement Module#append_features(or
>> Module#included), if that's what you want to know.
>
> No. Note the fine difference between include and extend (see code
> below).
> But anyway thanks for calling.
>
> Also, with a little magic you can add class and instance methods either
> way (i.e. with include and extend).
>
> Kind regards
>
> robert
>
>
Cheers,
Kent.
>>
>> On Dec 14, 2004, at 7:52 AM, Johan Nilsson wrote:
>>
>>>
>>> "Robert Klemme" <bob.news@gmx.net> wrote in message
>>> news:327uc2F3j9j3eU1@individual.net...
>>>>
>>>> "Johan Nilsson" <johan.nilsson@---.esrange.ssc.se> schrieb im
>>>> Newsbeitrag
>>>> news:1103018684.0021a1444d2417eb0d9c6eddf9e60f0d@teranews...
>>>>> Hi,
>>>>>
>>>>> some newbie questions:
>>>>>
>>>>> - How can/should I access a class constant from a mixin? The only
>>>>> thing
>>>> I've
>>>>> managed to get working is "const_get("name of const")".
>>>>> - Is it possible to access protected methods from mixins? I'm
>>>>> trying
>>>>> to
>>>>> create a mixin alike the following:
>>>>>
>>>>> ---
>>>>> module StaticCreateMixin
>>>>> def create_from(stuff)
>>>>> obj = self.new
>>>>> obj.my_stuff.<modifiying fn>!(stuff)
>>>>> obj
>>>>> end
>>>>> end
>>>>>
>>>>> class Foo
>>>>> extend StaticCreateMixin
>>>>>
>>>>> def my_stuff
>>>>> @stuff
>>>>> end
>>>>>
>>>>> protected :my_stuff
>>>>> end
>>>>>
>>>>> f = Foo.static_create("some stuff")
>>>>
>>>> Your example misses something, does it? It's not completely clear
>>>> to
>>>> me
>>>> what you want to do. Or did you misspell create_from as
>>>> static_create?
>>>
>>> Oops. Yes, I'm a very bad speller (or it could be the
>>> "extract-a-minimal-sample-from-actual-code-but-don't-bother-to-test-
>>> it"-synd
>>> rome).
>>>
>>> In english, I want to create an instance of Foo from within the
> mixin's
>>> supplied class method. The first question still applies though.
>>>
>>> // Johan
>>>
>>>
>>
>>
>>
>
>



Johan Nilsson

12/15/2004 8:46:00 AM

0


"Robert Klemme" <bob.news@gmx.net> wrote in message
news:328e5nF3jvaf9U1@individual.net...
>
> "Johan Nilsson" <johan.nilsson@---.esrange.ssc.se> schrieb im Newsbeitrag
> news:1103032112.3aa9129fd718fc17e4d9eb2e027a3e52@teranews...
> >
> > "Robert Klemme" <bob.news@gmx.net> wrote in message
> > news:3286taF3it29pU1@individual.net...
> > >
> >

[snip]

> >
> > I still don't see how the mixin can get to the protected methods
> though - I
> > get "NoMethodError: protected method 'my_stuff' called for ..." if I try
> > somehing like my original code.
>
> I haven't a solution for this yet. I tried with instance_eval but to no
> avail. Maybe send works. Did you try that?

No, and it actually works. What's the difference? I'm just starting to use
Ruby for real.

>
> > > > In english, I want to create an instance of Foo from within the
> mixin's
> > > > supplied class method. The first question still applies though.
> > >
> > > You mean like this?
> > >
> > > module Mix
> > > def test_it
> > > p self::FOO
> > > end
> > > end
> > >
> > > class Test
> > > extend Mix
> > > FOO = "bar"
> > > end
> >
> > Yes, but in my (unfortunately) more complex case I get "dynamic constant
> > assignment" whenever I add "self::<constant>" to the mixin (reported
> from
> > the point where the class constant is defined).
>
> But then you're assigning the constant more than once. From your example
> I though you just wanted to access (= read) it. Which Ruby version are
> you using?

Sorry for being unclear, but I'm not assigning more than once (at least I'm
not trying to). I'm trying to use either self::<constant> or
self.class.const_get(:<constant>) as rvalues, and the former does not work
in the Mixin. Oh, yes, and it is within a define_method scope - could that
matter, e.g.:

def ...
define_method(:initialize) { ||
...
@x = self::<constant> # dynamic constant assignment
...
}
end

Platform is Ruby 1.8.2.rc9 on WinXP.

[...some minute later...] Oh, but wait - self refers to the object here.
Trying to use self.class::ID works! Sorry for the noise.

>
> > Using
> > ...self.class.const_get("<constant>") works fine though in the mixin.
>
> Strange.
>
> > The code is a bit too much to post though, if I can reduce it I'll try
> and
> > post the actual failing code instead.
>
> Yeah, it would be good to see the real source of the problem. At the
> moment I feel a bit tapping in the dark. :-)

That might not be necessary any more, thanks!

// Johan

Robert Klemme

12/15/2004 10:33:00 AM

0


"Johan Nilsson" <johan.nilsson@---.esrange.ssc.se> schrieb im Newsbeitrag
news:1103100242.441c484f346652f8ca3ea31133c45618@teranews...
>
> "Robert Klemme" <bob.news@gmx.net> wrote in message
> news:328e5nF3jvaf9U1@individual.net...
> >
> > "Johan Nilsson" <johan.nilsson@---.esrange.ssc.se> schrieb im
Newsbeitrag
> > news:1103032112.3aa9129fd718fc17e4d9eb2e027a3e52@teranews...
> > >
> > > "Robert Klemme" <bob.news@gmx.net> wrote in message
> > > news:3286taF3it29pU1@individual.net...
> > > >
> > >
>
> [snip]
>
> > >
> > > I still don't see how the mixin can get to the protected methods
> > though - I
> > > get "NoMethodError: protected method 'my_stuff' called for ..." if I
try
> > > somehing like my original code.
> >
> > I haven't a solution for this yet. I tried with instance_eval but to
no
> > avail. Maybe send works. Did you try that?
>
> No, and it actually works. What's the difference? I'm just starting to
use
> Ruby for real.

#send bypasses a lot of things - that's why, I guess.

> > > > > In english, I want to create an instance of Foo from within the
> > mixin's
> > > > > supplied class method. The first question still applies though.
> > > >
> > > > You mean like this?
> > > >
> > > > module Mix
> > > > def test_it
> > > > p self::FOO
> > > > end
> > > > end
> > > >
> > > > class Test
> > > > extend Mix
> > > > FOO = "bar"
> > > > end
> > >
> > > Yes, but in my (unfortunately) more complex case I get "dynamic
constant
> > > assignment" whenever I add "self::<constant>" to the mixin (reported
> > from
> > > the point where the class constant is defined).
> >
> > But then you're assigning the constant more than once. From your
example
> > I though you just wanted to access (= read) it. Which Ruby version
are
> > you using?
>
> Sorry for being unclear, but I'm not assigning more than once (at least
I'm
> not trying to). I'm trying to use either self::<constant> or
> self.class.const_get(:<constant>) as rvalues, and the former does not
work
> in the Mixin. Oh, yes, and it is within a define_method scope - could
that
> matter, e.g.:

I think it does. self at the time of execution is an instance and not the
class object at hand.

> def ...
> define_method(:initialize) { ||
> ...
> @x = self::<constant> # dynamic constant assignment
> ...
> }
> end

So here are two alternatives:

def ...
define_method(:initialize) { ||
...
@x = self.class::<constant> # dynamic constant assignment
...
}
end


def ...
me = self
define_method(:initialize) { ||
...
@x = me::<constant> # dynamic constant assignment
...
}
end


> Platform is Ruby 1.8.2.rc9 on WinXP.
>
> [...some minute later...] Oh, but wait - self refers to the object here.
> Trying to use self.class::ID works! Sorry for the noise.
>
> >
> > > Using
> > > ...self.class.const_get("<constant>") works fine though in the
mixin.
> >
> > Strange.
> >
> > > The code is a bit too much to post though, if I can reduce it I'll
try
> > and
> > > post the actual failing code instead.
> >
> > Yeah, it would be good to see the real source of the problem. At the
> > moment I feel a bit tapping in the dark. :-)
>
> That might not be necessary any more, thanks!

You're welcome. I'm glad I could help.

Kind regards

robert