11/08/2018, 21:11
Road to ruby silver (Part 3)
This is just some note for who want to get Ruby Silver certification. :) Part1 Part2 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 ...
This is just some note for who want to get Ruby Silver certification. :)
Part1
Part2
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"