Mixin questions

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

"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

"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" <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

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" <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

"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.

>
> "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

···

On Dec 14, 2004, at 7:52 AM, Johan Nilsson wrote:
> supplied class method. The first question still applies though.
>
> // Johan
>
>

"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. :slight_smile:

Kind regards + good luck

    robert

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

Cheers,
Kent.

"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 10:37 AM, Robert Klemme wrote:

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" <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. :slight_smile:

That might not be necessary any more, thanks!

// Johan

"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. :slight_smile:

That might not be necessary any more, thanks!

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

Kind regards

    robert