Namespacing a class

Hello List,

what's the difference between:

- ---%<---
namespace A
  class B
    def foo
      # ...
    end
  end
end
- --->%---

and

- ---%<---
class C
  def bar
    # ...
  end
end
- --->%---

Besindes, of course, the naming (A::B vs C)?

TIA!

      Eric

Eric MSP Veith wrote:

what's the difference between:

- ---%<---
namespace A

you mean 'module A' ?

  class B
    def foo
      # ...
    end
  end
end
- --->%---

and

- ---%<---
class C
  def bar
    # ...
  end
end
- --->%---

Besindes, of course, the naming (A::B vs C)?

That's the main difference. Constant lookups are modified, e.g.
referring to 'D' inside B will look for A::b::D, A::smiley: or ::smiley: in that
order (I believe)

This can lead to some confusing errors, e.g.

module A
  class B
    def bar
      Socket.new('127.0.0.1',80)
    end
  end
end

when actually the problem is that you forgot to "require 'socket'"

···

A::B.new.bar # uninitialized constant A::b::Socket (NameError)
--
Posted via http://www.ruby-forum.com/\.

Brian,

> - ---%<---
> namespace A

you mean 'module A' ?

Err, yes, sorry. Freudian slip. :slight_smile:

> Besindes, of course, the naming (A::B vs C)?

That's the main difference. Constant lookups are modified, e.g.
referring to 'D' inside B will look for A::b::D, A::smiley: or ::smiley: in that
order (I believe)

Thank you for your answer! That clarifies a lot.

Modules are used for mixins. Is it possible -- and does it make sense at all
- -- to mixin a class into another class? I guess not?

TIA,
      Eric

···

On Monday 21 June 2010, Brian Candler <b.candler@pobox.com> wrote:

Eric MSP Veith wrote:

Modules are used for mixins. Is it possible -- and does it make sense at
all
- -- to mixin a class into another class? I guess not?

$ irb --simple-prompt

class A;end

=> nil

class B;include A;end

TypeError: wrong argument type Class (expected Module)
  from (irb):2:in `include'
  from (irb):2

···

--
Posted via http://www.ruby-forum.com/\.

Eric MSP Veith wrote:

Modules are used for mixins. Is it possible -- and does it make sense at all
- -- to mixin a class into another class? I guess not?

Actually, to add a bit to Brian's answer: it *is* possible and makes
perfect sense. It's just not allowed in Ruby, but it *is* allowed in
other languages.

jwm

Question answered. :slight_smile: Thank you!

···

On Monday 21 June 2010, Brian Candler <b.candler@pobox.com> wrote:

TypeError: wrong argument type Class (expected Module)
  from (irb):2:in `include'
  from (irb):2

Allowing classes to mixin other classes would change the class hierarchy from a tree to a directed acyclic graph. As soon as you do that you have to figure out how to manage the method lookup process along multiple paths. I don't think there is any sort of consensus on how to do that (i.e. different languages take different approaches) and so
I'm not sure 'makes perfect sense' is an accurate characterization of the solution space for that problem.

Gary Wright

···

On Jun 21, 2010, at 3:35 PM, Jörg W Mittag wrote:

Eric MSP Veith wrote:

Modules are used for mixins. Is it possible -- and does it make sense at all
- -- to mixin a class into another class? I guess not?

Actually, to add a bit to Brian's answer: it *is* possible and makes
perfect sense. It's just not allowed in Ruby, but it *is* allowed in
other languages.

Gary Wright wrote:

Eric MSP Veith wrote:

Modules are used for mixins. Is it possible -- and does it make sense at all
- -- to mixin a class into another class? I guess not?

Actually, to add a bit to Brian's answer: it *is* possible and makes
perfect sense. It's just not allowed in Ruby, but it *is* allowed in
other languages.

Allowing classes to mixin other classes would change the class
hierarchy from a tree to a directed acyclic graph. As soon as you
do that you have to figure out how to manage the method lookup
process along multiple paths. I don't think there is any sort of
consensus on how to do that (i.e. different languages take
different approaches) and so I'm not sure 'makes perfect sense' is
an accurate characterization of the solution space for that
problem.

You can take the algorithm Ruby uses for mixins and simply substitute
classes for modules and it would work exactly the way it does today,
including the linearization property.

The way mixins work in Ruby is (roughly) as follows (assume that we
want to mix ⟦M⟧ into a class ⟦C⟧, ignore for a moment the case of
mixing a mixin into another mixin):

1. create an anonymous class ⟦I⟧
2. set ⟦I⟧'s method table pointer to ⟦M⟧'s method table
3. set ⟦I⟧'s superclass to the ⟦C⟧'s singleton class's superclass
4. set ⟦C⟧'s singleton class's superclass to ⟦I⟧

In other words: create an anonymous class with the same methods but a
different identity as the mixin and insert it in the ancestor chain
directly above the singleton class.

There's really no need here for ⟦M⟧ to be a module, it could just as
well be a class. The linearization property depends on the fact that
mixin inclusion is done via a freshly minted anonymous class which has
no ancestors or descendants of its own: the include class ⟦I⟧ *only*
gets the methods from the mixin, it does not get its place in the
inheritance hierarchy. Whether the method table that ⟦I⟧ points to
used to belong to a module or a class is really irrelevant. It's just
a bag of methods.

The case of mixing in a mixin into another mixin is also handled
similar to the way it is today: currently, when you mix a module into
a module, it gets inserted above the module like it would above a
class. And then, when you mix a module ⟦M⟧ into a *class*, Ruby not
only constructs an include class for the ⟦M⟧'s method table, but
recursively also for all modules mixed into ⟦M⟧. Note that this means
that this mixin chain is only walked *once*, when you include ⟦M⟧ into
the class. If you later mix other modules into ⟦M⟧, their methods will
*not* be available to instances of the class.

Again, it would be possible to do just the same thing with classes
instead of modules: walk the chain of include classes and simply clone
them, then inject them into the ancestors chain like above.

That's what I meant by "makes perfect sense": you can take the exact
same algorithm that Ruby currently uses for module inclusion and use
it for class inclusion with the exact same results.

jwm

···

On Jun 21, 2010, at 3:35 PM, Jörg W Mittag wrote:

Gary Wright wrote:

Eric MSP Veith wrote:

Modules are used for mixins. Is it possible -- and does it make sense at all
- -- to mixin a class into another class? I guess not?

Actually, to add a bit to Brian's answer: it *is* possible and makes
perfect sense. It's just not allowed in Ruby, but it *is* allowed in
other languages.

You can take the algorithm Ruby uses for mixins and simply substitute
classes for modules and it would work exactly the way it does today,
including the linearization property.

The way mixins work in Ruby is (roughly) as follows (assume that we
want to mix ⟦M⟧ into a class ⟦C⟧, ignore for a moment the case of
mixing a mixin into another mixin):

1. create an anonymous class ⟦I⟧

Some would quibble with calling this an anonymous class instead of an
anonymous module, but that's a quibble.

2. set ⟦I⟧'s method table pointer to ⟦M⟧'s method table
3. set ⟦I⟧'s superclass to the ⟦C⟧'s singleton class's superclass
4. set ⟦C⟧'s singleton class's superclass to ⟦I⟧

In other words: create an anonymous class with the same methods but a
different identity as the mixin and insert it in the ancestor chain
directly above the singleton class.

There's really no need here for ⟦M⟧ to be a module, it could just as
well be a class. The linearization property depends on the fact that
mixin inclusion is done via a freshly minted anonymous class which has
no ancestors or descendants of its own: the include class ⟦I⟧ *only*
gets the methods from the mixin, it does not get its place in the
inheritance hierarchy. Whether the method table that ⟦I⟧ points to
used to belong to a module or a class is really irrelevant. It's just
a bag of methods.

The case of mixing in a mixin into another mixin is also handled
similar to the way it is today: currently, when you mix a module into
a module, it gets inserted above the module like it would above a
class. And then, when you mix a module ⟦M⟧ into a *class*, Ruby not
only constructs an include class for the ⟦M⟧'s method table, but
recursively also for all modules mixed into ⟦M⟧. Note that this means
that this mixin chain is only walked *once*, when you include ⟦M⟧ into
the class. If you later mix other modules into ⟦M⟧, their methods will
*not* be available to instances of the class.

Again, it would be possible to do just the same thing with classes
instead of modules: walk the chain of include classes and simply clone
them, then inject them into the ancestors chain like above.

That's what I meant by "makes perfect sense": you can take the exact
same algorithm that Ruby currently uses for module inclusion and use
it for class inclusion with the exact same results.

There's a lot of truth in this, but I think there are some subtleties.

Mixing in a class like this would support inheriting instance methods
from the mixed-in class, but not class methods. One of the
differences (and they are pretty small) between classes and modules in
Ruby is that if a class subclasses another, the subclass object
inherits the class methods from the superclass. Modules don't have
"super modules" so a mechanism for this isn't needed in the
implementation.

Now I suppose this could be handled by doing something similar to the
ancestry chain of the metaclass of the subclass, but personally, I
don't think this whole idea of mixing in classes is really that
attractive a feature.

···

2010/6/22 Jörg W Mittag <JoergWMittag+Ruby@googlemail.com>:

On Jun 21, 2010, at 3:35 PM, Jörg W Mittag wrote:

--
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Github: rubyredrick (Rick DeNatale) · GitHub
Twitter: @RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

What you describe might work well enough for pure-ruby classes, but if
you tried to mix a core class (Array, String) into another class, the
result would be segfaults. Maybe the same would be true of any class
implemented in C? Not sure.

···

On 6/22/10, Jörg W Mittag <JoergWMittag+Ruby@googlemail.com> wrote:

Gary Wright wrote:

On Jun 21, 2010, at 3:35 PM, Jörg W Mittag wrote:

Eric MSP Veith wrote:

Modules are used for mixins. Is it possible -- and does it make sense at
all
- -- to mixin a class into another class? I guess not?

Actually, to add a bit to Brian's answer: it *is* possible and makes
perfect sense. It's just not allowed in Ruby, but it *is* allowed in
other languages.

Allowing classes to mixin other classes would change the class
hierarchy from a tree to a directed acyclic graph. As soon as you
do that you have to figure out how to manage the method lookup
process along multiple paths. I don't think there is any sort of
consensus on how to do that (i.e. different languages take
different approaches) and so I'm not sure 'makes perfect sense' is
an accurate characterization of the solution space for that
problem.

You can take the algorithm Ruby uses for mixins and simply substitute
classes for modules and it would work exactly the way it does today,
including the linearization property.

The way mixins work in Ruby is (roughly) as follows (assume that we
want to mix ⟦M⟧ into a class ⟦C⟧, ignore for a moment the case of
mixing a mixin into another mixin):

1. create an anonymous class ⟦I⟧
2. set ⟦I⟧'s method table pointer to ⟦M⟧'s method table
3. set ⟦I⟧'s superclass to the ⟦C⟧'s singleton class's superclass
4. set ⟦C⟧'s singleton class's superclass to ⟦I⟧

In other words: create an anonymous class with the same methods but a
different identity as the mixin and insert it in the ancestor chain
directly above the singleton class.

There's really no need here for ⟦M⟧ to be a module, it could just as
well be a class. The linearization property depends on the fact that
mixin inclusion is done via a freshly minted anonymous class which has
no ancestors or descendants of its own: the include class ⟦I⟧ *only*
gets the methods from the mixin, it does not get its place in the
inheritance hierarchy. Whether the method table that ⟦I⟧ points to
used to belong to a module or a class is really irrelevant. It's just
a bag of methods.

The case of mixing in a mixin into another mixin is also handled
similar to the way it is today: currently, when you mix a module into
a module, it gets inserted above the module like it would above a
class. And then, when you mix a module ⟦M⟧ into a *class*, Ruby not
only constructs an include class for the ⟦M⟧'s method table, but
recursively also for all modules mixed into ⟦M⟧. Note that this means
that this mixin chain is only walked *once*, when you include ⟦M⟧ into
the class. If you later mix other modules into ⟦M⟧, their methods will
*not* be available to instances of the class.

Again, it would be possible to do just the same thing with classes
instead of modules: walk the chain of include classes and simply clone
them, then inject them into the ancestors chain like above.

That's what I meant by "makes perfect sense": you can take the exact
same algorithm that Ruby currently uses for module inclusion and use
it for class inclusion with the exact same results.

I believe the more important point is that - although classes and
modules have only few differences (inheritance, instance creation) -
they are deliberately kept separate because they are language
artifacts intended to model different concepts (entities vs.
behavior). Even if it is technically possible to mix in classes the
same way as modules (and I believe Jörg's assessment is correct here)
it probably does not make much sense to allow this from a conceptual
point of view.

Kind regards

robert

···

2010/6/24 Caleb Clausen <vikkous@gmail.com>:

On 6/22/10, Jörg W Mittag <JoergWMittag+Ruby@googlemail.com> wrote:

Gary Wright wrote:

On Jun 21, 2010, at 3:35 PM, Jörg W Mittag wrote:

Eric MSP Veith wrote:

Modules are used for mixins. Is it possible -- and does it make sense at
all
- -- to mixin a class into another class? I guess not?

Actually, to add a bit to Brian's answer: it *is* possible and makes
perfect sense. It's just not allowed in Ruby, but it *is* allowed in
other languages.

Allowing classes to mixin other classes would change the class
hierarchy from a tree to a directed acyclic graph. As soon as you
do that you have to figure out how to manage the method lookup
process along multiple paths. I don't think there is any sort of
consensus on how to do that (i.e. different languages take
different approaches) and so I'm not sure 'makes perfect sense' is
an accurate characterization of the solution space for that
problem.

You can take the algorithm Ruby uses for mixins and simply substitute
classes for modules and it would work exactly the way it does today,
including the linearization property.

The way mixins work in Ruby is (roughly) as follows (assume that we
want to mix ⟦M⟧ into a class ⟦C⟧, ignore for a moment the case of
mixing a mixin into another mixin):

1. create an anonymous class ⟦I⟧
2. set ⟦I⟧'s method table pointer to ⟦M⟧'s method table
3. set ⟦I⟧'s superclass to the ⟦C⟧'s singleton class's superclass
4. set ⟦C⟧'s singleton class's superclass to ⟦I⟧

In other words: create an anonymous class with the same methods but a
different identity as the mixin and insert it in the ancestor chain
directly above the singleton class.

There's really no need here for ⟦M⟧ to be a module, it could just as
well be a class. The linearization property depends on the fact that
mixin inclusion is done via a freshly minted anonymous class which has
no ancestors or descendants of its own: the include class ⟦I⟧ *only*
gets the methods from the mixin, it does not get its place in the
inheritance hierarchy. Whether the method table that ⟦I⟧ points to
used to belong to a module or a class is really irrelevant. It's just
a bag of methods.

The case of mixing in a mixin into another mixin is also handled
similar to the way it is today: currently, when you mix a module into
a module, it gets inserted above the module like it would above a
class. And then, when you mix a module ⟦M⟧ into a *class*, Ruby not
only constructs an include class for the ⟦M⟧'s method table, but
recursively also for all modules mixed into ⟦M⟧. Note that this means
that this mixin chain is only walked *once*, when you include ⟦M⟧ into
the class. If you later mix other modules into ⟦M⟧, their methods will
*not* be available to instances of the class.

Again, it would be possible to do just the same thing with classes
instead of modules: walk the chain of include classes and simply clone
them, then inject them into the ancestors chain like above.

That's what I meant by "makes perfect sense": you can take the exact
same algorithm that Ruby currently uses for module inclusion and use
it for class inclusion with the exact same results.

What you describe might work well enough for pure-ruby classes, but if
you tried to mix a core class (Array, String) into another class, the
result would be segfaults. Maybe the same would be true of any class
implemented in C? Not sure.

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

I disagree. This sort of explanation has no material bases --how does
the conceptual distinction help us? I think it hurts us for a few
reasons.

1) It disrupts auto-creation of namespaces. E.g.

  class Y::X
  end

What is Y, a class or module? Because of the distinction between class
and module you have to pre-define it. This futher leads to "bottom
requiring" --using require at the bottom of scripts instead of at the
top.

2) The developer is forced to choose between two arbitrarily limited
mechanisms for modeling behavior. Classes can only re-used once per
subclass and not at all via modules. Modules can be reused extensively
but do not naturally include their singleton methods. These
limitations lead to a number of code smells from overly limited use of
inheritance to included/ClassMethods hooks.

3) Using tools for conceptually different cases does not require that
their be physically different tools for each case. I wrench is just as
good for tightening a nut as it is for loosening one. If I had to use
two separate tools it would be quite annoying.

Following your conceptual distinction argument we could just as easily
argue for separate entities for mixins and namespaces since those are
also different uses of modules. Clearly no one wants that.

I have never heard of a solid reason for the division between classes
and modules --my guess is that there is no real reason other than that
it how it was done originally, and changing it now means 1) a major
version bump and 2) an overhaul of the implementation.

···

On Jun 24, 6:48 am, Robert Klemme <shortcut...@googlemail.com> wrote:

I believe the more important point is that - although classes and
modules have only few differences (inheritance, instance creation) -
they are deliberately kept separate because they are language
artifacts intended to model different concepts (entities vs.
behavior). Even if it is technically possible to mix in classes the
same way as modules (and I believe Jörg's assessment is correct here)
it probably does not make much sense to allow this from a conceptual
point of view.

I believe the more important point is that - although classes and
modules have only few differences (inheritance, instance creation) -
they are deliberately kept separate because they are language
artifacts intended to model different concepts (entities vs.
behavior). Even if it is technically possible to mix in classes the
same way as modules (and I believe Jörg's assessment is correct here)
it probably does not make much sense to allow this from a conceptual
point of view.

I disagree. This sort of explanation has no material bases --how does
the conceptual distinction help us? I think it hurts us for a few
reasons.

1) It disrupts auto-creation of namespaces. E.g.

class Y::X
end

What is Y, a class or module? Because of the distinction between class
and module you have to pre-define it. This futher leads to "bottom
requiring" --using require at the bottom of scripts instead of at the
top.

I don't understand what you mean here. Can you elaborate or provide an example?

2) The developer is forced to choose between two arbitrarily limited
mechanisms for modeling behavior. Classes can only re-used once per
subclass and not at all via modules. Modules can be reused extensively
but do not naturally include their singleton methods. These
limitations lead to a number of code smells from overly limited use of
inheritance to included/ClassMethods hooks.

Why is not including their singleton methods a strong limitation?

3) Using tools for conceptually different cases does not require that
their be physically different tools for each case. I wrench is just as
good for tightening a nut as it is for loosening one. If I had to use
two separate tools it would be quite annoying.

I believe this is a bad analogy. If at all you would have to take
"tightening and loosing nuts" and "hammering". In that case it's
quite obvious that you would not normally use the same tool for the
job.

Following your conceptual distinction argument we could just as easily
argue for separate entities for mixins and namespaces since those are
also different uses of modules. Clearly no one wants that.

Actually I thought about mentioning this because namespacing is yet
another concept which happens to have two tools - module and class.
It probably feels very natural because all major OO languages do
support this. And it does have some merits.

I have never heard of a solid reason for the division between classes
and modules --my guess is that there is no real reason other than that
it how it was done originally, and changing it now means 1) a major
version bump and 2) an overhaul of the implementation.

I find that distinction pretty clear as I have tried to point out
earlier. Somehow you seem to be using the language quite differently
than me and have run into limitations that do not exist for me. Maybe
we can take the discussion a bit further to find out more about this.

Kind regards

robert

···

2010/6/24 Intransition <transfire@gmail.com>:

On Jun 24, 6:48 am, Robert Klemme <shortcut...@googlemail.com> wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

I don't understand what you mean here. Can you elaborate or provide an example?

# lib/foo/baz.rb

class Foo::Baz
  ...
end

# lib/foo.rb

require 'foo/baz'

class Foo
  ...
end

> 2) The developer is forced to choose between two arbitrarily limited
> mechanisms for modeling behavior. Classes can only re-used once per
> subclass and not at all via modules. Modules can be reused extensively
> but do not naturally include their singleton methods. These
> limitations lead to a number of code smells from overly limited use of
> inheritance to included/ClassMethods hooks.

Why is not including their singleton methods a strong limitation?

Well it is strong. In fact, if it wasn't for that, the difference be
almost ephemeral. But strong != good. I know that matz has cited this
issue in the past, but I have never seen an explanation of why it is
so bad to get the module singleton methods? Clearly in many cases that
is exactly what people want, which is why they ClassMethods hack is so
common. If it were the other way around, and the singleton methods
were passed along, but you didn't want them to be... well I would like
to know under what circumstances that it would really be a problem. If
those singleton methods were simply being used as functions (M.f) then
they can easily be placed in a separate module. If they were being
used as a DSL for the module itself, why would the including class be
any worse off by gaining the DSL too? Maybe there is some reason one
can find, but even so it seems to me that it must be the rarity. In
all my use of modules I can't think of case where having the singleton
level would have been a problem and in many, if not most, I actually
wanted it and had to resort to some hoop jumping.

In fact, and I think this is worth pointing out... I never ever design
a module to be utilized via #extend. In such usecases I actually do
this:

  module M
    def self.append_features(base)
      base.extend self
    end
  end

Of course, rather than fuss about it, we could also have the best of
both worlds (imagine that). I, for one, would be happy with a new
method to go along with #include and #extend that provided both
singleton and instance levels.

> 3) Using tools for conceptually different cases does not require that
> their be physically different tools for each case. I wrench is just as
> good for tightening a nut as it is for loosening one. If I had to use
> two separate tools it would be quite annoying.

I believe this is a bad analogy. If at all you would have to take
"tightening and loosing nuts" and "hammering". In that case it's
quite obvious that you would not normally use the same tool for the
job.

Maybe so. But a class is a subclass of module. So they are very
similar tools, unlike a hammer and a wrench. My point was simply that,
as craftsman, we'd rather have just one tool, if it can do the job two
just as well.

> Following your conceptual distinction argument we could just as easily
> argue for separate entities for mixins and namespaces since those are
> also different uses of modules. Clearly no one wants that.

Actually I thought about mentioning this because namespacing is yet
another concept which happens to have two tools - module and class.
It probably feels very natural because all major OO languages do
support this. And it does have some merits.

> I have never heard of a solid reason for the division between classes
> and modules --my guess is that there is no real reason other than that
> it how it was done originally, and changing it now means 1) a major
> version bump and 2) an overhaul of the implementation.

I find that distinction pretty clear as I have tried to point out
earlier. Somehow you seem to be using the language quite differently
than me and have run into limitations that do not exist for me. Maybe
we can take the discussion a bit further to find out more about this.

Perhaps b/c I have done a lot of meta-programming? Not sure. It would
be interesting to know more, I agree.

···

On Jun 24, 11:58 am, Robert Klemme <shortcut...@googlemail.com> wrote:

--
remember.guy do |as, often| as.you_can - without endhttp://blog.rubybestpractices.com/

I don't understand what you mean here. Can you elaborate or provide an example?

# lib/foo/baz.rb

class Foo::Baz
...
end

# lib/foo.rb

require 'foo/baz'

class Foo
...
end

I always thought the proper idiom was

# lib/foo.rb

class Foo
...
end

# optionally:
require 'foo/baz'

# lib/foo/baz.rb

require 'foo'

class Foo::Baz
...
end

Alternative:

# lib/foo.rb

class Foo
...
  autoload :Baz, 'foo/baz'
end

# lib/foo/baz.rb
(as above)

> 2) The developer is forced to choose between two arbitrarily limited
> mechanisms for modeling behavior. Classes can only re-used once per
> subclass and not at all via modules. Modules can be reused extensively
> but do not naturally include their singleton methods. These
> limitations lead to a number of code smells from overly limited use of
> inheritance to included/ClassMethods hooks.

Why is not including their singleton methods a strong limitation?

Well it is strong.

That's a strange answer to my question...

In fact, if it wasn't for that, the difference be
almost ephemeral. But strong != good. I know that matz has cited this
issue in the past, but I have never seen an explanation of why it is
so bad to get the module singleton methods? Clearly in many cases that
is exactly what people want, which is why they ClassMethods hack is so
common.

Let my first try to understand what you mean. If I get you properly you want

module A
  def self.wok
    puts "I work for the class"
  end

  def foo
    puts "happy instance"
    self.class.wok
  end
end

class X
  include A
end

X.new.foo ->
"happy instance"
"I work for the class"

I personally would write

  def foo
    puts "happy instance"
    A.wok
  end

and be done so I suspect you mean something else.

If it were the other way around, and the singleton methods
were passed along, but you didn't want them to be... well I would like
to know under what circumstances that it would really be a problem. If
those singleton methods were simply being used as functions (M.f) then
they can easily be placed in a separate module. If they were being
used as a DSL for the module itself, why would the including class be
any worse off by gaining the DSL too? Maybe there is some reason one
can find, but even so it seems to me that it must be the rarity.

If I get your drift you want to use a single module to define a DSL
and apply it at the same time, e.g.

module DSL
  def self.smart_attribute(sym)
    class_eval "def #{sym}; puts 'Look Ma, how smart I am!'; @#{sym}; end"
  end

  smart_attribute :name
end

and then

class Foo
  include DSL

  smart_attribute :age
end

f = Foo.new
f.name
f.age

I personally would separate the DSL out into another module because
that is more modular. Not all classes might need smart attribute
"name" so this would be a better choice IMHO.

In
all my use of modules I can't think of case where having the singleton
level would have been a problem and in many, if not most, I actually
wanted it and had to resort to some hoop jumping.

In fact, and I think this is worth pointing out... I never ever design
a module to be utilized via #extend. In such usecases I actually do
this:

module M
def self.append_features(base)
base.extend self
end
end

Of course, rather than fuss about it, we could also have the best of
both worlds (imagine that). I, for one, would be happy with a new
method to go along with #include and #extend that provided both
singleton and instance levels.

I believe automatically propagating class methods might cause
confusion because it is not obvious. At least I haven't had the need
for this (which might be due to the different tasks we tackle with
Ruby).

> 3) Using tools for conceptually different cases does not require that
> their be physically different tools for each case. I wrench is just as
> good for tightening a nut as it is for loosening one. If I had to use
> two separate tools it would be quite annoying.

I believe this is a bad analogy. If at all you would have to take
"tightening and loosing nuts" and "hammering". In that case it's
quite obvious that you would not normally use the same tool for the
job.

Maybe so. But a class is a subclass of module. So they are very
similar tools, unlike a hammer and a wrench. My point was simply that,
as craftsman, we'd rather have just one tool, if it can do the job two
just as well.

> Following your conceptual distinction argument we could just as easily
> argue for separate entities for mixins and namespaces since those are
> also different uses of modules. Clearly no one wants that.

Actually I thought about mentioning this because namespacing is yet
another concept which happens to have two tools - module and class.
It probably feels very natural because all major OO languages do
support this. And it does have some merits.

> I have never heard of a solid reason for the division between classes
> and modules --my guess is that there is no real reason other than that
> it how it was done originally, and changing it now means 1) a major
> version bump and 2) an overhaul of the implementation.

I find that distinction pretty clear as I have tried to point out
earlier. Somehow you seem to be using the language quite differently
than me and have run into limitations that do not exist for me. Maybe
we can take the discussion a bit further to find out more about this.

Perhaps b/c I have done a lot of meta-programming? Not sure. It would
be interesting to know more, I agree.

I believe this points into the right direction. I'm not doing as much
meta programming - probably because I am not involved in creating
frameworks in Ruby. I rather use the language to solve day to day
problems. So far my need for DSL's has been scarce. So where were
you really hurt by not automatically propagating class methods? I
can't think of a case but obviously you have one in mind.

Thanks for the discussion!

Kind regards

robert

···

2010/6/25 Intransition <transfire@gmail.com>:

On Jun 24, 11:58 am, Robert Klemme <shortcut...@googlemail.com> wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Sorry about the delay... you know how it is!

I always thought the proper idiom was

# lib/foo.rb

class Foo
...
end

# optionally:
require 'foo/baz'

# lib/foo/baz.rb

require 'foo'

class Foo::Baz
...
end

Not always feasible, especially if you are loading a whole directory
of "pluggable" files. In which case you either bottom require of use
a separate file. I just as soon not have to worry about it either way
and if class and module where the same type of object then we wouldn't
have to.

Alternative:

# lib/foo.rb

class Foo
...
autoload :Baz, 'foo/baz'
end

I do not ever use autoload, as much as I might like to. It has a known
bug --it will not use a customized require. I used a customized
require in my development environment, so it is useless to me. (and
really the one thing that pisses the most... but thats' another story)

# lib/foo/baz.rb
(as above)

>> > 2) The developer is forced to choose between two arbitrarily limited
>> > mechanisms for modeling behavior. Classes can only re-used once per
>> > subclass and not at all via modules. Modules can be reused extensively
>> > but do not naturally include their singleton methods. These
>> > limitations lead to a number of code smells from overly limited use of
>> > inheritance to included/ClassMethods hooks.

>> Why is not including their singleton methods a strong limitation?

> Well it is strong.

That's a strange answer to my question...

Let my first try to understand what you mean. If I get you properly you want

module A
def self.wok
puts "I work for the class"
end

def foo
puts "happy instance"
self.class.wok
end
end

class X
include A
end

X.new.foo ->
"happy instance"
"I work for the class"

I personally would write

def foo
puts "happy instance"
A.wok
end

and be done so I suspect you mean something else.

Well that's one thing. But look what happens:

  class Y < X
    def self.wok
      "ain't going to happen"
    end
  end

You've strapped the implementation to a specific module, so there is
no way to override behavior in a subclass (short of overriding every
method that uses #wok).

> If it were the other way around, and the singleton methods
> were passed along, but you didn't want them to be... well I would like
> to know under what circumstances that it would really be a problem. If
> those singleton methods were simply being used as functions (M.f) then
> they can easily be placed in a separate module. If they were being
> used as a DSL for the module itself, why would the including class be
> any worse off by gaining the DSL too? Maybe there is some reason one
> can find, but even so it seems to me that it must be the rarity.

If I get your drift you want to use a single module to define a DSL
and apply it at the same time, e.g.

module DSL
def self.smart_attribute(sym)
class_eval "def #{sym}; puts 'Look Ma, how smart I am!'; @#{sym}; end"
end

smart_attribute :name
end

and then

class Foo
include DSL

smart_attribute :age
end

f = Foo.new
f.name
f.age

I personally would separate the DSL out into another module because
that is more modular. Not all classes might need smart attribute
"name" so this would be a better choice IMHO.

Well, you could do that. But that's not really the main issue.
Probably the most significant issue is with super:

  module M
    def self.x; "M"; end
  end

  class X
    include M
    def self.x
      super
    end
  end

You get an error. If it wasn't for this class inheritable attributes
would be completely trivial to implement.

Another more clear case is where the DSL defines a method that uses
another method the instance level as an overridable piece of
functionality.

  module DSL
    def self.smart_attribute(sym)
      class_eval "def #{sym}; puts message + ' ' + @#{sym}.to_s; end"
    end

    # Default message is 'Look Ma, a smart:'.
    def message
      'Look Ma, a smart:'
    end
  end

Not being able to do this, you have to do more difficult meta-
programming tricks to achieve the same result.

> all my use of modules I can't think of case where having the singleton
> level would have been a problem and in many, if not most, I actually
> wanted it and had to resort to some hoop jumping.

> In fact, and I think this is worth pointing out... I never ever design
> a module to be utilized via #extend. In such usecases I actually do
> this:

> module M
> def self.append_features(base)
> base.extend self
> end
> end

> Of course, rather than fuss about it, we could also have the best of
> both worlds (imagine that). I, for one, would be happy with a new
> method to go along with #include and #extend that provided both
> singleton and instance levels.

I believe automatically propagating class methods might cause
confusion because it is not obvious. At least I haven't had the need
for this (which might be due to the different tasks we tackle with
Ruby).

To me, not propagating them is "not obvious" --anything that creates
more work for me, when the alternative has no significant issues,
seems "not obvious" :wink:

>> > 3) Using tools for conceptually different cases does not require that
>> > their be physically different tools for each case. I wrench is just as
>> > good for tightening a nut as it is for loosening one. If I had to use
>> > two separate tools it would be quite annoying.

>> I believe this is a bad analogy. If at all you would have to take
>> "tightening and loosing nuts" and "hammering". In that case it's
>> quite obvious that you would not normally use the same tool for the
>> job.

I believe this points into the right direction. I'm not doing as much
meta programming - probably because I am not involved in creating
frameworks in Ruby. I rather use the language to solve day to day
problems. So far my need for DSL's has been scarce. So where were
you really hurt by not automatically propagating class methods? I
can't think of a case but obviously you have one in mind.

Look at Anise, look at Facets Inheritor. And wherever you find the
ClassMethods hack, that is a case, and there are many of those around.

···

On Jun 25, 8:30 am, Robert Klemme <shortcut...@googlemail.com> wrote:

Sorry about the delay... you know how it is!

No problem.

I always thought the proper idiom was

# lib/foo.rb

class Foo
  ...
end

# optionally:
require 'foo/baz'

# lib/foo/baz.rb

require 'foo'

class Foo::Baz
  ...
end

Not always feasible, especially if you are loading a whole directory
of "pluggable" files. In which case you either bottom require of use
a separate file. I just as soon not have to worry about it either way
and if class and module where the same type of object then we wouldn't
have to.

Hmm, personally I would prefer loading those pluggable files explicitly - even if via a special method that only passes a directory name. Library code typically resides in a different location than user extensions so for me this makes more sense. In that case I would do

class Foo
   def self.load_plugins(dir_or_file)
     ...
   end
end

and then

require 'foo'

Foo.load_plugins ENV["HOME"] + "/foo_extension"

You could even make it more implicit by defaulting to an environment variable.

class Foo
   def self.load_plugins(dir_or_file = ENV['FOO_PLUGINS'])
     ...
   end
end

Alternative:

# lib/foo.rb

class Foo
  ...
   autoload :Baz, 'foo/baz'
end

I do not ever use autoload, as much as I might like to. It has a known
bug --it will not use a customized require. I used a customized
require in my development environment, so it is useless to me. (and
really the one thing that pisses the most... but thats' another story)

Indeed, that's a downside. OTOH, I'd rather opt for fixing that then neglecting autoload. It is apparent: I don't do gem development and I rarely use gems. :slight_smile:

# lib/foo/baz.rb
(as above)

2) The developer is forced to choose between two arbitrarily limited
mechanisms for modeling behavior. Classes can only re-used once per
subclass and not at all via modules. Modules can be reused extensively
but do not naturally include their singleton methods. These
limitations lead to a number of code smells from overly limited use of
inheritance to included/ClassMethods hooks.

Why is not including their singleton methods a strong limitation?

Well it is strong.

That's a strange answer to my question...

Let my first try to understand what you mean. If I get you properly you want

module A
   def self.wok
     puts "I work for the class"
   end

   def foo
     puts "happy instance"
     self.class.wok
   end
end

class X
   include A
end

X.new.foo ->
"happy instance"
"I work for the class"

I personally would write

   def foo
     puts "happy instance"
     A.wok
   end

and be done so I suspect you mean something else.

Well that's one thing. But look what happens:

   class Y< X
     def self.wok
       "ain't going to happen"
     end
   end

You've strapped the implementation to a specific module, so there is
no way to override behavior in a subclass (short of overriding every
method that uses #wok).

Hmm, I see your point. I am wondering though whether that might not be too much magic.

If it were the other way around, and the singleton methods
were passed along, but you didn't want them to be... well I would like
to know under what circumstances that it would really be a problem. If
those singleton methods were simply being used as functions (M.f) then
they can easily be placed in a separate module. If they were being
used as a DSL for the module itself, why would the including class be
any worse off by gaining the DSL too? Maybe there is some reason one
can find, but even so it seems to me that it must be the rarity.

If I get your drift you want to use a single module to define a DSL
and apply it at the same time, e.g.

module DSL
   def self.smart_attribute(sym)
     class_eval "def #{sym}; puts 'Look Ma, how smart I am!'; @#{sym}; end"
   end

   smart_attribute :name
end

and then

class Foo
   include DSL

   smart_attribute :age
end

f = Foo.new
f.name
f.age

I personally would separate the DSL out into another module because
that is more modular. Not all classes might need smart attribute
"name" so this would be a better choice IMHO.

Well, you could do that. But that's not really the main issue.
Probably the most significant issue is with super:

   module M
     def self.x; "M"; end
   end

   class X
     include M
     def self.x
       super
     end
   end

You get an error. If it wasn't for this class inheritable attributes
would be completely trivial to implement.

Ah, I see! It seems for the class level methods one needs a second module which is automatically used to extend a class that includes the visible module. I agree, that's a bit clumsy.

module X
   module Xcl
     def bar
       puts "X::bar"
     end
   end

   def self.included cl
     cl.extend Xcl
   end

   def foo
     puts "foo"
     self.class.bar
   end
end

class A
   include X

   def self.bar
     puts "A::bar"
     super
   end

end

irb(main):042:0* A.new.foo
foo
X::bar
=> nil

But not really hard.

Another more clear case is where the DSL defines a method that uses
another method the instance level as an overridable piece of
functionality.

   module DSL
     def self.smart_attribute(sym)
       class_eval "def #{sym}; puts message + ' ' + @#{sym}.to_s; end"
     end

     # Default message is 'Look Ma, a smart:'.
     def message
       'Look Ma, a smart:'
     end
   end

Not being able to do this, you have to do more difficult meta-
programming tricks to achieve the same result.

all my use of modules I can't think of case where having the singleton
level would have been a problem and in many, if not most, I actually
wanted it and had to resort to some hoop jumping.

In fact, and I think this is worth pointing out... I never ever design
a module to be utilized via #extend. In such usecases I actually do
this:

  module M
    def self.append_features(base)
      base.extend self
    end
  end

Of course, rather than fuss about it, we could also have the best of
both worlds (imagine that). I, for one, would be happy with a new
method to go along with #include and #extend that provided both
singleton and instance levels.

I believe automatically propagating class methods might cause
confusion because it is not obvious. At least I haven't had the need
for this (which might be due to the different tasks we tackle with
Ruby).

To me, not propagating them is "not obvious" --anything that creates
more work for me, when the alternative has no significant issues,
seems "not obvious" :wink:

:slight_smile: I think we agree to disagree here.

3) Using tools for conceptually different cases does not require that
their be physically different tools for each case. I wrench is just as
good for tightening a nut as it is for loosening one. If I had to use
two separate tools it would be quite annoying.

I believe this is a bad analogy. If at all you would have to take
"tightening and loosing nuts" and "hammering". In that case it's
quite obvious that you would not normally use the same tool for the
job.

I believe this points into the right direction. I'm not doing as much
meta programming - probably because I am not involved in creating
frameworks in Ruby. I rather use the language to solve day to day
problems. So far my need for DSL's has been scarce. So where were
you really hurt by not automatically propagating class methods? I
can't think of a case but obviously you have one in mind.

Look at Anise, look at Facets Inheritor. And wherever you find the
ClassMethods hack, that is a case, and there are many of those around.

Ok, I'll try to.

Kind regards

  robert

···

On 27.06.2010 21:26, Intransition wrote:

On Jun 25, 8:30 am, Robert Klemme<shortcut...@googlemail.com> wrote:

A::bar

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Just a quick follow up to this --I would love to hear a clear case
where passing along the singleton methods would cause a serious issue
that couldn't easily be overcome.