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"