Inverse Operation of Module#include

Hi list,

Is there a built-in inverse operation of Module#include? Currently I have:

class A
end

module B
   def foo
     :b
   end
end

module C
   def foo
     :c
   end
end

a = A.new

class A
   include B
end
p a.foo # => :b

class A
   include C
end
p a.foo # => :c

class A
   include B
end
p a.foo # => :c

So if module B has already been mixed in, it cannot be re-included again thus the foo method is not redefined to B#foo in the last include operation. Thus occurs to me when I use Inversion of Control (or dependency injection) to switch between various implementations of a certain interface. I was thinking that if I can somehow "exclude" the module and include it again then the problem would be solved, and hence the question.

Or better yet, is there another way to achieve this kind of implementation switching?

Regards,

Su

Maybe you want to undef the method before including a module.

···

On Fri, Dec 2, 2011 at 2:57 PM, Su Zhang <su.comp.lang.ruby@gmail.com> wrote:

Hi list,

Is there a built-in inverse operation of Module#include? Currently I have:

class A
end

module B
def foo
:b
end
end

module C
def foo
:c
end
end

a = A.new

class A
include B
end
p a.foo # => :b

class A
include C
end
p a.foo # => :c

class A
include B
end
p a.foo # => :c

So if module B has already been mixed in, it cannot be re-included again
thus the foo method is not redefined to B#foo in the last include operation.
Thus occurs to me when I use Inversion of Control (or dependency injection)
to switch between various implementations of a certain interface. I was
thinking that if I can somehow "exclude" the module and include it again
then the problem would be solved, and hence the question.

Or better yet, is there another way to achieve this kind of implementation
switching?

Regards,

Su

I think there unfortunately is not.

It would be neat if behaviour could be reversed easily on objects.

···

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

BTW, what do you want to achieve, switch interface at run-time or
switch implementation at run-time?

My "un" gem will do the trick, but there is nothing built in

···

On Dec 1, 2011, at 22:57, Su Zhang <su.comp.lang.ruby@gmail.com> wrote:

Is there a built-in inverse operation of Module#include? Currently I have:

Hi list,

Is there a built-in inverse operation of Module#include? Currently I have:

[snip code]

So if module B has already been mixed in, it cannot be re-included again
thus the foo method is not redefined to B#foo in the last include operation.
Thus occurs to me when I use Inversion of Control (or dependency injection)
to switch between various implementations of a certain interface. I was
thinking that if I can somehow "exclude" the module and include it again
then the problem would be solved, and hence the question.

Or better yet, is there another way to achieve this kind of implementation
switching?

Regards,

Su

You could do this:

#!/usr/bin/env ruby
class A
end

module B
  def self.included(other)
    other.class_eval {
      def foo
        :b
      end
    }
  end
end

module C
  def self.included(other)
    other.class_eval {
      def foo
        :c
      end
    }
  end
end

a = A.new

class A
  include B
end
p a.foo # => :b

class A
  include C
end
p a.foo # => :c

class A
  include B
end
p a.foo # => :b

Regards,
Sean

···

On Fri, Dec 2, 2011 at 6:57 AM, Su Zhang <su.comp.lang.ruby@gmail.com> wrote:

I would suggest an Adapter pattern use here. IF there is something that has
functionality that you want to have shared, and one thing changes, I would
make different subclasses. Example:

class Team # Base class

def play
  raise "You should use a subclass of Team."
end

end

class FootballTeam < Team # Adapter to a football team

def play
  play_football
end

end

class BaseballTeam < Team # Adapter to a baseball team

def play
  play_baseball
end

end

···

On Fri, Dec 2, 2011 at 3:24 AM, Ryan Davis <ryand-ruby@zenspider.com> wrote:

On Dec 1, 2011, at 22:57, Su Zhang <su.comp.lang.ruby@gmail.com> wrote:

> Is there a built-in inverse operation of Module#include? Currently I
have:

My "un" gem will do the trick, but there is nothing built in

--
Sincerely,

Isaac Sanders
Section C-4B Vice Chief, Order of the Arrow
Vice Chief of Administration, Tecumseh #65
Eagle Scout

I tried that, but that will not remove the mixed-in module from the inheritance chain, so including that same module again still does nothing. The methods I undef'ed will simply be marked undefined and the caller will no longer be able to call them.

···

On 12/2/2011 2:35 AM, Yong Li wrote:

Maybe you want to undef the method before including a module.

The latter. In my example code the interface `foo' is not changed but there exists several implementations.

···

On 12/2/2011 2:51 AM, Yong Li wrote:

BTW, what do you want to achieve, switch interface at run-time or
switch implementation at run-time?

That's good to know, I will definitely give it a try :slight_smile:

···

On 12/2/2011 3:24 AM, Ryan Davis wrote:

My "un" gem will do the trick, but there is nothing built in

Abstract base classes are silly in Ruby; why bother with that
inheritance? Just take advantage of duck typing.

The Team class is totally useless.

Hi Issac,

What if Team inherits from Group, and both FootballTeam and BaseballTeam depend on some common interface defined in both Team and Group, and I want to alter the implementations for Group at runtime?

For example:

class Group
   def cheer
     # drink_beer or have_barbecue?
   end
end

class Team < Group
   def consult
     analyze_tactics
   end
end

class FootballTeam < Team
   def cheer
     super
     shout
   end
end

class BaseballTeam < Team
   def cheer
     super
     roar
   end
end

team = FootballTeam.new
team.cheer
team.consult

team = BaseballTeam.new
team.cheer
team.consult

Both types of team share the common Team#consult method, but I cannot be sure if I should do drink_beer or have_barbecue in Group#cheer until runtime, and I want to separate them as different implementations. With module mixin, all the implementations are nicely injected into the inheritance chain. If we derive from Group, the derived class will not be on the same inheritance chain as FootballTeam or BaseballTeam.

Su

···

On 12/2/2011 6:22 AM, Isaac Sanders wrote:

I would suggest an Adapter pattern use here. IF there is something that has
functionality that you want to have shared, and one thing changes, I would
make different subclasses. Example:

class Team # Base class

def play
   raise "You should use a subclass of Team."
end

end

Then, you probably can consider making different implementations as
"objects" and switch these objects in A at run-time.

class A
  def setImpl(implementation)
    @impl=implementation
  end

  def foo
    impl.foo
  end
  #other methods of the interface
end

class ImplB
  include B
end
class ImplC
  include C
end

#at run-time
a = A.new
a.setImpl(ImplB.new)
a.foo #=> call b.foo

a.setImpl(ImplC.new)
a.foo #=> call c.foo

a.setImpl(ImplB.new)
a.foo #=> call b.foo

of course, you may need further modifications if module B accesses A's
private methods

···

On Sat, Dec 3, 2011 at 1:54 AM, Su Zhang <su.comp.lang.ruby@gmail.com> wrote:

On 12/2/2011 2:51 AM, Yong Li wrote:

BTW, what do you want to achieve, switch interface at run-time or
switch implementation at run-time?

The latter. In my example code the interface `foo' is not changed but there
exists several implementations.

--
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Li, Yong
Fushan Road 450, Room 9A
Pudong New Area,
Shanghai, 200122
P.R.China

phone: +86-15021003368
email: gilbertly@gmail.com
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

The way I have it implemented, but if it were to have a lot of
functionality, it may be worth using this pattern.

However, I am a noob, and I am inclined to differ to you.

···

On Fri, Dec 2, 2011 at 7:49 AM, Steve Klabnik <steve@steveklabnik.com>wrote:

Abstract base classes are silly in Ruby; why bother with that
inheritance? Just take advantage of duck typing.

The Team class is totally useless.

--
Sincerely,

Isaac Sanders

Steve,

Could you point to an example or description of why you consider abstract
base classes pointless?

I was under the impression that it does make sense to have an abstract
base class that has a number of generic methods and then derived classes:
* add some specific methods
* add some specific attributes
* override some of the inherited methods

I have a specific example I was just implementing with an abstract
base class for an "account" (think "bank account"). There are different
derived classes, e.g. for simple money, but also for credits. Certain
functions are generic (e.g. balance), but certain functions are specific
(e.g. put funds on the account will use decimals for "money", but only
accept integers for "credits"). I have put some demo code below.

Very curious to hear how this design could be improved with duck typing.

Many thanks,

Peter

···

On Fri, Dec 2, 2011 at 1:49 PM, Steve Klabnik <steve@steveklabnik.com>wrote:

Abstract base classes are silly in Ruby; why bother with that
inheritance? Just take advantage of duck typing.

The Team class is totally useless.

+++++++++++++++++++++++
demo code:

$ cat derived.rb
class Account

  require 'bigdecimal'

  def initialize
    @balance = 0
  end

  def balance
   @balance
  end

  def put(amount)
    # do some locking
    @balance += amount
    # release lock
  end
end

class MoneyAccount < Account
  def put(amount)
    raise "you can only put decimal amounts in a MoneyAccount" unless
amount.is_a?(BigDecimal)
    super
  end
end

class CreditAccount < Account
  def put(amount)
    raise "you can only put integer amounts in a CreditAccount" unless
amount.is_a?(Integer)
    super
  end
end

$ irb
1.9.3p0 :001 > require './derived.rb'
=> true
1.9.3p0 :002 > ma = MoneyAccount.new
=> #<MoneyAccount:0x9d3b9f0 @balance=0>
1.9.3p0 :003 > ma.put 3.14
RuntimeError: you can only put decimal amounts in a MoneyAccount
    from /home/peterv/data/derived.rb:23:in `put'
    from (irb):3
    from /home/peterv/.rvm/rubies/ruby-1.9.3-p0/bin/irb:16:in `<main>'
1.9.3p0 :004 > ma.put(BigDecimal.new("3.14"))
=> #<BigDecimal:9c2fd90,'0.314E1',18(36)>
1.9.3p0 :005 > ma.balance
=> #<BigDecimal:9c2fd90,'0.314E1',18(36)>
1.9.3p0 :006 > ma.balance.to_s
=> "0.314E1"
1.9.3p0 :007 > ca = CreditAccount.new
=> #<CreditAccount:0x9c2591c @balance=0>
1.9.3p0 :008 > ca.balance
=> 0
1.9.3p0 :009 > ca.put(BigDecimal.new("2.71"))
RuntimeError: you can only put integer amounts in a CreditAccount
    from /home/peterv/data/derived.rb:30:in `put'
    from (irb):9
    from /home/peterv/.rvm/rubies/ruby-1.9.3-p0/bin/irb:16:in `<main>'
1.9.3p0 :010 > ca.put(36)
=> 36
1.9.3p0 :011 > ca.balance
=> 36

If you want to redefine a function, and the adapter pattern does not seem
like a fit, I might use something like this:

Group.class_eval do
  def cheer
    # Then you can redefine your method here.
  end
end

Peter Vandenabeele wrote in post #1034787:

Very curious to hear how this design could be improved with duck typing.

Correct me if I'm wrong, but I think Steve was trying to say that using
__abstract__ base classes are useless. I mean, it's just there to raise
an exception, but the exception would have been raised anyway (a
NotMethodError). In Ruby, interface is everything, so instead of seeing
if something is a kind_of? Team, just check if it responds_to? :play and
code the interface that way.

In your case, the base class is taking care of things that all accounts
do. In my view, this is a fine, and it's not __really__ a ruby abstract
base class because you're not raising explicit exceptions on abstract
methods. In your case, this is just a base class, not an 'abstract' base
class. Abstract base classes have purely abstract methods that are just
useless in ruby. If however, you're providing real implementation
through actual methods that do stuff, this isn't an abstract base class
but just a base class.

As for passing through the module chain, i came up with a quick hacky
way of doing it after reading through this thread.

class A
end

module B
  MODULE = :b
  def foo(mod=nil)
    if respond_to? :passable?
      return(super) unless mod == MODULE
    end
    'from module B'
  end
end

module C
  MODULE = :c
  def foo(mod=nil)
    if respond_to? :passable?
      return(super) unless mod == MODULE
    end
    'from module C'
  end
end

a = A.new

class A
  include B
end

p a.foo => 'from module B'

class A
  include C
end

p a.foo => 'from module C'

module Passable
  def passable?
    true
  end
end

a.extend Passable

p a.foo :b => 'from module B'
p a.foo :c => 'from module C'

Pretty straightforward, and could be rewritten fairly easily to pass all
methods on to super if that were required. Tell me what you guys think.
I think undef'ing a method is fairly brutal in this situation.

-Luke

···

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

Abstract base classes are silly in Ruby; why bother with that
inheritance? Just take advantage of duck typing.

I was under the impression that it does make sense to have an abstract
base class that has a number of generic methods and then derived classes:
* add some specific methods
* add some specific attributes
* override some of the inherited methods

=> Template method pattern

I have a specific example I was just implementing with an abstract
base class for an "account" (think "bank account"). There are different
derived classes, e.g. for simple money, but also for credits. Certain
functions are generic (e.g. balance), but certain functions are specific
(e.g. put funds on the account will use decimals for "money", but only
accept integers for "credits"). I have put some demo code below.

Very curious to hear how this design could be improved with duck typing.

Not really duck typing, but this is how template method could look in this case

class Account
  def initialize
    extend MonitorMixin
    @balance = 0
  end

  def balance
    synchronize do
      @balance
    end
  end

  def put(amount)
    ensure_proper_amount(amount)

    synchronize do
      @balance += amount
    end
  end

end

class MoneyAccount < Account
  def ensure_proper_amount(amount)
    raise "you can only put decimal amounts in a MoneyAccount" unless
      BigDecimal === amount
  end
end

Kind regards

robert

···

On Fri, Dec 2, 2011 at 7:28 PM, Peter Vandenabeele <peter@vandenabeele.com> wrote:

On Fri, Dec 2, 2011 at 1:49 PM, Steve Klabnik <steve@steveklabnik.com>wrote:

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

Peter Vandenabeele wrote in post #1034787:

> Very curious to hear how this design could be improved with duck typing.

Correct me if I'm wrong, but I think Steve was trying to say that using
__abstract__ base classes are useless. I mean, it's just there to raise
an exception, but the exception would have been raised anyway (a
NotMethodError). In Ruby, interface is everything, so instead of seeing
if something is a kind_of? Team, just check if it responds_to? :play and
code the interface that way.

Aha, thanks for the detailed reply.

Now, just for my understanding of duck typing, assume both derived classes
(BaseballTeam and FootballTeam) have a method with the name :play, but
they require a different argument signature (like in my put example where
MoneyAccount#play needs a BigDecimal and CreditAccount#play needs an
integer). Should I then still use the class to determine how to call the
method, or should I better name these 2 methods differently?

In your case, the base class is taking care of things that all accounts
do. In my view, this is a fine, and it's not __really__ a ruby abstract
base class because you're not raising explicit exceptions on abstract
methods. In your case, this is just a base class, not an 'abstract' base
class. Abstract base classes have purely abstract methods that are just
useless in ruby. If however, you're providing real implementation
through actual methods that do stuff, this isn't an abstract base class
but just a base class.

OK, got it. So on the criterion of actual functionality, it is not an
abstract
base class, but still, it is not the intention to ever create an instance
of the Base class, only of the derived classes.

Thx,

Peter

···

On Fri, Dec 2, 2011 at 7:47 PM, luke gruber <luke.gru@gmail.com> wrote:

>
>> Abstract base classes are silly in Ruby; why bother with that
>> inheritance? Just take advantage of duck typing.

> I was under the impression that it does make sense to have an abstract
> base class that has a number of generic methods and then derived classes:
> * add some specific methods
> * add some specific attributes
> * override some of the inherited methods

=> Template method pattern

Thx for that pointer. I am still not clear what Steve exactly meant with
his comment.

> I have a specific example I was just implementing with an abstract
> base class for an "account" (think "bank account"). There are different
> derived classes, e.g. for simple money, but also for credits. Certain
> functions are generic (e.g. balance), but certain functions are specific
> (e.g. put funds on the account will use decimals for "money", but only
> accept integers for "credits"). I have put some demo code below.
>
> Very curious to hear how this design could be improved with duck typing.

Not really duck typing, but this is how template method could look in this
case

class Account
def initialize
   extend MonitorMixin
    @balance = 0
end

def balance
    synchronize do
     @balance
   end
end

def put(amount)
   ensure_proper_amount(amount)

   synchronize do
     @balance += amount
   end
  end

end

class MoneyAccount < Account
  def ensure_proper_amount(amount)
    raise "you can only put decimal amounts in a MoneyAccount" unless
      BigDecimal === amount
end
end

If I understand correctly the improvement in your version is that you only
override exactly that part that is different for the derived class vs. the
generic
class (the "ensure_proper_amount" validation). Nice, thanks.

With respect to the locking strategy you propose. I am actually reading and
writing the amount from an SQL database with ActiveRecord, from potentially
multiple parallel processes (multiple Rails processes from passenger,
potentially even on different servers). Am I correct that this locking
strategy with
MonitorMixin would not be relevant (default Rails passenger set-up with
multiple processes, but no multi-threading inside a process). I believe a
different locking strategy would be required, e.g. acquiring a lock from the
database or from another source of locking that is shared between the
different processes (multiple processes per server and multiple servers).

Thanks,

Peter

···

On Sun, Dec 4, 2011 at 7:23 PM, Robert Klemme <shortcutter@googlemail.com>wrote:

On Fri, Dec 2, 2011 at 7:28 PM, Peter Vandenabeele > <peter@vandenabeele.com> wrote:
> On Fri, Dec 2, 2011 at 1:49 PM, Steve Klabnik <steve@steveklabnik.com > >wrote: