Extending class

In Ruby it is possible to extend module, but not class. I am working on
a mongoid rails application where one collection(table) is defined like:

class User
include Mongoid::Document

field :username, type: String
field :title, type: String
end

In my scenario somewhere in the future someone would make a gem, which
would need to extend User class. I found out that it can be done this
way:

User::field :signature, type: String
User::belongs_to :visit
User::embeds_many :roles

but it is kinda ugly. Then I realize that extend keyword exists, but it
is possible to extend only modules not classes. So this realy nice
example would work only if User is a module.

class UserForForum
extend User

field :signature, type: String

belongs_to :visit
embeds_many :roles
end

Is there a clear way of extending classes?

by
TheR

On Wed, 09 Jan 2013 23:12:31 +0100, Damjan R. [email protected]
wrote:

Is there a clear way of extending classes?

extend Something is mostly the same as class << self; include Something; end.

The class << something syntax opens the “singleton class” (aka
“eigenclass”) of something; include is just your regular include.

For example:

module MyModule
def test; puts “Hello world!”; end
end

class MyClass
class << self
include MyModule
end
end

MyClass.test # => Hello world!

The combination means that the methods included from MyModule end up as
class methods of MyClass.

Hello,

I don’t know if my tip applies for you (haven’t worked with neither
Rails nor Mongoid), but your scenario looks like subclassing is the way
to go; you have a UserForForum class, which is a more specialized form
of User.

A way of extending a class like a module doesn’t exist in Ruby afaik.

Regards,

Calvin

On Wed, Jan 9, 2013 at 11:33 PM, Calvin Bornhofen
[email protected] wrote:

Hello,

I don’t know if my tip applies for you (haven’t worked with neither Rails
nor Mongoid), but your scenario looks like subclassing is the way to go; you
have a UserForForum class, which is a more specialized form of User.

I also believe that is what is called for here.

A way of extending a class like a module doesn’t exist in Ruby afaik.

Well, it does because you can extend anything:

irb(main):001:0> module M; def honk; puts “—”; end end
=> nil
irb(main):002:0> o = Object.new
=> #Object:0x8004cf9c
irb(main):003:0> o.extend M
=> #Object:0x8004cf9c
irb(main):004:0> o.honk

=> nil

Kind regards

robert

On 10/01/2013, at 8:29 PM, Robert K. wrote:

Well, it does because you can extend anything:

Pretty sure the OP wants to do this

1.9.3p327 :001 > class M; def honk; puts “—”; end end
=> nil
1.9.3p327 :002 > o = Object.new
=> #Object:0x007fb679293268
1.9.3p327 :003 > o.extend M
TypeError: wrong argument type Class (expected Module)

Henry

On Wed, Jan 9, 2013 at 10:12 PM, Damjan R. [email protected]
wrote:
[snip]

Inheritance?

class UserForForum < User

field :signature, type: String

belongs_to :visit
embeds_many :roles

end

Regards,
Sean

On Thu, Jan 10, 2013 at 10:35 PM, Henry M. [email protected]
wrote:

1.9.3p327 :002 > o = Object.new
=> #Object:0x007fb679293268
1.9.3p327 :003 > o.extend M
TypeError: wrong argument type Class (expected Module)

I’m pretty sure that he does not want that.

Kind regards

robert