about class and module

R

Ruby Newbee

Hello,

Coz Ruby's class and module are close to Perl's, I think it's not hard
to understand for them.
I wrote a note below for learning them, if I'm not correct, please
point it out, thanks.


1. class is defined with the keyword of "class", module is defined
with the keyword of "module".

for example, define a class:

class Myclass
def echo (a,b)
puts a + b
end
end

define a module:

module Mymod
def echo (a,b)
puts a+b
end
end


2. If we want to call the methods in a class, need to instantiate the
class with "new" (except the class method).
If we want to call the methods in a module, need to include it
(except the module method).

call the methods in a class:

class Myclass
def echo (a,b)
puts a + b
end
end

x = Myclass.new
x.echo("hello","world")

call the methods in a module:

module Mymod
def echo (a,b)
puts a+b
end
end

include Mymod
echo "hello","world"


3. class itself has class method, module itself has module method.
if we call a class method or a module method, won't use "new" or "include".

the class method:

class Myclass
def Myclass.echo(a)
puts a
end
end

Myclass.echo("hello world")

the module method:

class Mymod
def Mymod.echo(a)
puts a
end
end

Mymod.echo "hello world"


4. the calling and called relationship between class and module:

A module can contain methods, constants, other modules, and even classes.
A module can inherit from another module, but it may not inherit from a class.
As a class may include a module, it may also include modules that have
inherited other modules.
 
B

Brian Candler

Ruby said:
Coz Ruby's class and module are close to Perl's, I think it's not hard
to understand for them.
I wrote a note below for learning them, if I'm not correct, please
point it out, thanks.

Worth also pointing out:

* class Class inherits from class Module

* a class *is* a module

* the extra functionality that a class has, over and above a module, is
that you can create an instance of a class.
2. If we want to call the methods in a class, need to instantiate the
class with "new" (except the class method).
If we want to call the methods in a module, need to include it
(except the module method).

In addition: Objects have singleton classes, which are private to that
object. You can use 'extend' to add a module to an individual object's
singleton class.

module Foo
def greet
puts "Hello, #{self}!"
end
end
s = "you"
s.extend Foo
s.greet # => "Hello, you!"

Note we have not touched class String at this point.

But since classes are objects too, the same applies to classes. You can
use a module to add "class methods" to a class.

String.extend Foo
String.greet # => "Hello, String!"
3. class itself has class method, module itself has module method.

There are also 'module functions', defined like this:

module Foo
def bar
puts "hello"
end
module_function :bar
end

Foo.bar

(There is a subtle difference between this and def Foo.bar, see if you
can work it out...)
4. the calling and called relationship between class and module:

A module can contain methods, constants, other modules, and even
classes.

What do you mean by "contain" here?

irb(main):026:0> module X
irb(main):027:1> end
=> nil
irb(main):028:0> class Y
irb(main):029:1> include X
irb(main):030:1> end
=> Y
irb(main):031:0> module Z
irb(main):032:1> include Y
irb(main):033:1> end
TypeError: wrong argument type Class (expected Module)
from (irb):32:in `include'
from (irb):32
from :0

5. modules (and hence also classes) form a namespace mechanism, which is
entirely orthogonal to inheritance and the method call chain.

module X
class Y
Z = 3
end
end

puts X::Y::Z
y = X::Y.new

This is maybe what you were alluding to in point 4, because you
mentioned constants. But it must be stated this is *nothing* to do with
inheritance at all.
 
R

Ruby Newbee

In addition: Objects have singleton classes, which are private to that
object. You can use 'extend' to add a module to an individual object's
singleton class.

module Foo
=C2=A0def greet
=C2=A0 =C2=A0puts "Hello, #{self}!"
=C2=A0end
end
s =3D "you"
s.extend Foo
s.greet =C2=A0 =C2=A0 =C2=A0 =C2=A0 # =3D> "Hello, you!"

Note we have not touched class String at this point.

But since classes are objects too, the same applies to classes. You can
use a module to add "class methods" to a class.

String.extend Foo
String.greet =C2=A0 =C2=A0# =3D> "Hello, String!"

Thanks for the points. That looks very interesting.
As you said "Objects have singleton classes", what's "singleton
class"? could you show a description by examples?
I never saw that before. Thanks again.
 
B

Brian Candler

Ruby said:
As you said "Objects have singleton classes", what's "singleton
class"? could you show a description by examples?

s1 = "a string"
s2 = "another string"

def s1.wibble
puts "bibble"
end

s1.wibble # => "bibble"
s2.wibble # => NoMethodError: undefined method `wibble'

Every object has a 'singleton class' which contains methods private to
that object.

A class, like class Foo, is an instance of class Class. So the 'class
methods' of Foo are just methods in the singleton class of Foo.

class Foo; end
def Foo.wibble
puts "I am a singleton method"
end
Foo.wibble

Another way to add methods into the singleton class is like this:

s1 = "hello"
class << s1
def hey; puts "hey!"; end
end
s1.hey

So of course this works for classes (and class methods) too:

class Foo
class << self
def bar
puts "In bar"
end
end
end
Foo.bar

The singleton class is itself an object. It's quite hard to grab hold
of, but the above gives you a clue to the trick:

s = "hello"
sc = class << s; self; end

So sometimes you will see code like this:

class << s; self; end.class_eval { define_method:)bar) { puts "bar!" }
}

An object with a singleton class loses it when it is dup'd (otherwise it
wouldn't be a singleton any more :)

a = "hello"
def a.world; puts "world"; end
b = a.dup
a.world # "world"
b.world # NoMethodError: undefined method `world'
 
B

Brian Candler

Brian said:
Every object has a 'singleton class' which contains methods private to
that object.

I shouldn't have said "private to", because private methods are
something else.

"methods unique to that object" would have been better.
 
J

Jesús Gabriel y Galán

Thanks for the points. That looks very interesting.
As you said "Objects have singleton classes", what's "singleton
class"? could you show a description by examples?
I never saw that before. Thanks again.

A singleton class of an object (also referred sometimes as eigenclass
or metaclass, although there has been much debate about which term to
use), is a special class that can be attached to each object to
specify per-object behaviour. This means, a place where you put
methods that can only be called on a specific instance. Brian already
gave you an example by means of extending an object with a module.
Here are some other examples:

irb(main):001:0> s =3D "hello"
=3D> "hello"
irb(main):006:0> def s.to_upper_case
irb(main):007:1> self.upcase
irb(main):008:1> end
=3D> nil
irb(main):009:0> s.to_upper_case
=3D> "HELLO"

As you can see we define a method for s, and only s, this is the only
object which will have the method to_upper_case. No other string will
have it. As Brian pointed out, you can extend a single object with a
module, and what this does is add the module's methods to the
singleton class of the object:

irb(main):010:0> module Testing
irb(main):011:1> def test
irb(main):012:2> "what a test !"
irb(main):013:2> end
irb(main):014:1> end
=3D> nil
irb(main):015:0> s.extend Testing
=3D> "hello"
irb(main):016:0> s.test
=3D> "what a test !"

(s is the previous string). This strategy is a really good way to add
functionality to object, since you don't mess with core classes (which
can break things), but only act on the specific objects you want to
modify.

In Ruby, classes are objects too (they are instances of the Class class):

irb(main):017:0> String.class
=3D> Class

This means that they also have a singleton class where to place
methods that can only be called on that specific object. As the object
is a class, they are usually called class methods, but they are not
really different to singleton methods on any object:

irb(main):018:0> def String.test
irb(main):019:1> "testing again"
irb(main):020:1> end
=3D> nil
irb(main):021:0> String.test
=3D> "testing again"

Hope this helps,

Jesus.
 
R

Ruby Newbee

Thanks a lot Brian and Jesus.
In my last years experience of programming, I never met something like
singleton class.
It seems so flexible and useful. I will put it into my practice.
So ruby has some really better features than others, and thanks all
for the always kind helps.

// Jenni
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top