Help us understand the problem. What is going on with this article?

Road to ruby silver (Part 3)

More than 1 year has passed since last update.

This is just some note for who want to get Ruby Silver certification. :)

Part 1
Part 2

Chapter 4: Object orientation

4.1. Define a class

4.1.1. Syntax

class <<ClassName>>
end

Sample:

class Foo
  def initialize a = 0
    @a = a
  end

  def method1
    @a
  end
end

foo1 = Foo.new(1)
foo1.method1 ⇛ 1
foo2 = Foo.new
foo2.method1 ⇛ 0

★ All commands is not contained in any method will be ran when class is loaded

puts 1
class Hoge
  puts 2
end
puts 3

⇛
1
2
3

4.1.2. Instance method and initialization method

class Foo
  def initialize a = 0
    @a = a
  end

  def method1
    @a
  end
end

⇛ method1 is an instance method of class Foo

foo1 = Foo.new
foo1.class == Foo ⇛ true

4.1.3. Inheritance class (クラス継承)

class FooExt < Foo
  def initialize a, b
    @b = b
    super a
  end

  def method2
    @a + @b
  end
end

fooExt = FooExt.new(3, 4)
fooExt.method1 ⇛ 3
fooExt.method2 ⇛ 7

FooExt.superclass ⇛ Foo

4.1.4. super

For calling the nearest parent class

4.2. Instance method

4.2.1. Class object (クラスオブジェクト)

  • Create new instance of class Foo
instance1 = Foo.new(1)
instance2 = Foo.new(1)

instance1.object_id ⇛ 70323462947500
instance2.object_id ⇛ 70323462930480
Foo.object_id ⇛ 70323462538720

4.2.2. What method will be called?

class Foo
  def initialize a
    @a = a
  end

  def get_a
    @a
  end
end

class FooExt
  def initialize a, b
    super a
    @b = b
  end

  def get_a
    puts "FooExt get_a: #{@a}"
  end

  def get_b
    puts "FooExt get_b: #{@b}"
  end
end

foo = Foo.new 3
foo.get_a
⇛ 3
foo.get_b
⇛ NameError
foo_ext = FooExt.new 3, 4
foo_ext.get_a
⇛ "FooExt get_a: 3"
foo_ext.get_b
⇛ 4

4.2.3. Inheritance chain and method_missing

  • For above example:
FooExt => Foo => Object => Kernel => BasicObject
  • Get all ancestors of a class
Foo.ancestors
⇛ [Foo, Object, Kernel, BasicObject]
FooExt.ancestors
⇛ [FooExt, Foo, Object, Kernel, BasicObject]
  • Check a class is interiting an other class
Foo < BasicObject
⇛ true
Foo < FooExt
⇛ false
  • instance_methods and instance_variables
Foo.instance_methods(false)
⇛ [:method1]
FooExt.instance_methods(false)
⇛ [:method2]
Foo.instance_variables
⇛ []
FooExt.instance_variables
⇛ []
foo1.instance_variables
⇛ [:@a]
fooExt.instance_variables
⇛ [:@b, :@a]
  • alias
alias new_method_name old_method_name
alias new_global_var_name old_global_var_name
  • undef
undef method_name
undef method1_name, method2_name

Sample:

class Test
  def method1; end

  def method2; end

  alias :method3 :method2
  undef :method2
end

Test.instance_methods(false)
⇛ [:method1, :method3]

class Test2
  def method1; end

  def method2; end

  alias :method3 :method2
  undef :method3
end

Test2.instance_methods(false)
⇛ [:method1, :method2]
  • Override method_missing method
class Test
  def method_missing m, *args
    puts "called: Test##{m}"
    super
  end
end

Test.new.do_not_existed_method
⇛ called: Test#do_not_existed_method
NoMethodError: undefined method `do_not_existed_method' for #<Test:0x007feaea84dc08>

4.2.4. Open class

  • All classes in Ruby are open. This means you can define new method for any other class.
class Test
  def method1
    "method1"
  end
end

Test.object_id
⇛ 70119510391780

t1 = Test.new
t1.method1
⇛ "method1"
t1.method2
⇛ NameError

class Test
  def method2
    "method2"
  end
end

Test.object_id
⇛ 70119510391780

t2 = Test.new
t2.method1
⇛ "method1"
t2.method2
⇛ "method2"
t1.method2
⇛ "method2"

★ Attention: There is attention when you reopen a class that is extending an other class.

class A; end
class B; end
class C < B
end

①
class C < A
end
⇛ TypeError
②
class C < B
end
⇛ OK
③
class C
end
⇛ OK

4.3. Mix-in (Modules)

4.3.1. Module definition and include

  • Some attentions about module:
    • Can not create instance for module
    • Can not inherit
    • Can be included in class or other module
module A; end
A.new ⇛ NoMethodError

module B < A
end
⇛ SyntaxError
  • Module definition syntax
module <<module_name>>
  def method_name
  end
end
  • Module is not inheritable ⇛ Ancestor of it contains only it.
module TestModule
  def method1
    "method1"
  end
end

TestModule.ancestors
⇛ [TestModule]

TestModule.instance_methods
⇛ [:method1]
  • Include module to a class
class B
  include TestModule
end

b = B.new
b.method1
⇛ "method1"
B.instance_methods(false)
⇛ [] # :method1 is not defined inside of B ⇛ do not appear in here
  • Check all modules a class is including
module A; end
module B; end

class Test1
  include A
end

class Test2 < Test1
  include B
end

Test1.included_modules
⇛ [A, Kernel]
Test2.included_modules
⇛ [A, B, Kernel]

4.3.2. Load flow when include module

module TestModule
  def method1
    "TestModule#method1"
  end
end

class A
  include TestModule

  def method1
    "A#method1"
  end
end

class B
  def method1
    "B#method1"
  end

  include TestModule
end

A.new.method1 ⇛ "A#method1"
B.new.method1 ⇛ "B#method1"

4.4. Singleton class

4.4.1. Class method

  • Definition
class A; end
def A.class_method_1
  "class_method_1"
end

A.class_method_1
⇛ "class_method_1"

A.new.class_method_1
⇛ NoMethodError
  • Define method for only 1 instance
class Foo; end

foo1 = Foo.new
foo2 = Foo.new

foo1.object_id ⇛ 70175903036120
foo1.class ⇛ Foo

def foo1.method_1
  "method_1"
end

foo1.object_id ⇛ 70175903036120
foo1.class ⇛ Foo
foo1.class.instance_methods ⇛ []

foo1.method_1
⇛ "method_1"
foo2.method_1
⇛ NoMethodError

When define method for only instance foo1,
system will create an singleton class like:

class #foo1 < Foo
  def method_1
  end
end

and foo1 is setted as the instance of class #foo1

4.4.2. Singleton class

  • Definition sample
①
class Foo; end

foo1 = Foo.new
singleton_class = class << foo1
  self
end

singleton_class
⇛ #<Class:#<Foo:0x007ff2fd810c48>>

②
class Foo; end

foo2 = Foo.new
class << foo2
  def method1
    "method1"
  end
end

foo2.method1 ⇛ "method1"
  • Define new method inside an other method
class A
  def method1
    def method2
    end
  end
end

A.instance_methods ⇛ [:method1]
A.new.method1
A.instance_methods ⇛ [:method1, :method2]

4.4.3. extend

  • Sample of using mix-in in singleton class
module TestModule
  def method1; "method1"; end
end
class Foo; end
foo1 = Foo.new
class << foo1
  include TestModule
end

foo1.method1 ⇛ "method1"
  • Use extend
module TestModule
  def method1; "method1"; end
end

class Foo; end
foo1 = Foo.new
foo1.extend(TestModule)
foo1.method1 ⇛ "method1"
temona
"てもなく"とは「簡単に、たやすく」という意味を持った古語です。 テモナの社名にはIT技術で世の中を便利にしたいという想いが込められています。
http://temona.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away