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

···

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

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

···

On Wed, 09 Jan 2013 23:12:31 +0100, Damjan Rems <lists@ruby-forum.com> wrote:

Is there a clear way of extending classes?

--
Matma Rex

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 09.01.2013 23:12, Damjan Rems wrote:

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?

[snip]

class UserForForum
extend User

field :signature, type: String

belongs_to :visit
embeds_many :roles
end

Is there a clear way of extending classes?

Inheritance?

  class UserForForum < User

    field :signature, type: String

    belongs_to :visit
    embeds_many :roles
  end

Regards,
Sean

···

On Wed, Jan 9, 2013 at 10:12 PM, Damjan Rems <lists@ruby-forum.com> 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

···

On Wed, Jan 9, 2013 at 11:33 PM, Calvin Bornhofen <calvin.bornhofen@web.de> wrote:
---
=> nil

Kind regards

robert

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

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 10/01/2013, at 8:29 PM, Robert Klemme wrote:

Well, it does because you can extend *anything*:

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

Kind regards

robert

···

On Thu, Jan 10, 2013 at 10:35 PM, Henry Maddocks <hmaddocks@me.com> wrote:

On 10/01/2013, at 8:29 PM, Robert Klemme 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)

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