On Aug 14, 2011, at 11:40 AM, I=F1aki Baz Castillo wrote:

> 2011/8/14 Chris White <cwprogram / live.com>:
>> This behavior can fortunately be overridden by simply overriding the =
hello method in the B class, meaning that it will use the constant =
defined in B instead
>=20
> Yes, but it requires duplicating code. In my case I've a server class:
>=20
>=20
> class Server
>  def self.foo
>    puts "I listen in IP #{IP}"
>  end
> end
>=20
>=20
> and then some classes inhereting from it:
>=20
>=20
> class UdpServer < Server
>  IP =3D "1.2.3.4"
> end
>=20
> class TcpServer < Server
>  IP =3D "1.2.3.5"
> end
>=20
>=20
> Of course "TcpServer.foo" fails:
>=20
>  NameError: uninitialized constant Server::IP
>=20

I suppose the question then becomes why they have to be constants at =
that level. By using a module and doing a mixin (as I notice that Philip =
just mentioned as I'm writing this):

-------------------------------------
module Server
  def listen(ip)
    # Would most likely set instance variable @ip for later use
    @ip =3D ip
    puts "Listening on #@ip"
  end
end

class UdpServer
 include Server

 def listen(ip)
  puts "UDP Listen"
  super
 end
end

class TcpServer
 include Server
end

TcpServer.new.listen("1.2.3.4")
UdpServer.new.listen("1.2.3.5")
-------------------------------------

The listen logic is centralized, and as shown in the UdpServer class, =
you can override the Server listen and still call its core functionality =
through `super`. This works out because including modules inserts into =
the object hierarchy as shown by doing a p TcpServer.ancestors:

[TcpServer, Server, Object, Kernel, BasicObject]=20

Regards,
Chris White
http://www.twitter.com/cwgem=