Road to Ruby Silver (Part 4)
This is just some note for who want to get Ruby Silver certification. :) Part 1 Part 2 Part 3 4.5. Class Method 4.5.1. Class Class ① Example about using class method class Foo; end foo_class = Foo.class → Class ② Create an instance of class Class 2.1. Foo = ...
This is just some note for who want to get Ruby Silver certification. :)
Part 1
Part 2
Part 3
4.5. Class Method
4.5.1. Class Class
① Example about using class method
class Foo; end foo_class = Foo.class → Class
② Create an instance of class Class
2.1. Foo = Class.new Foo.new.class → Foo 2.2. FooExt = Class.new(Foo) do # → Foo is super class def initialize b # → Init method of FooExt class super() @b = b end def method_2 c # → Instance method method_2 @b + c end end
4.5.2. Define a class method
①
class Class def new_method puts "This method will be applied as a class method of any class" end end class Foo; end Foo.new_method → This method will be applied as a class method of any class String.new_method → This method will be applied as a class method of any class
②
class Foo def Foo.new_method puts "This is Foo.new_method" end end Foo.new_method → This is Foo.new_method
③
class Foo def self.new_method puts "New method of Foo" end end Foo.new_method → "New method of Foo"
④
class Foo class << self def new_method puts "new_method" end end end Foo.new_method → "new_method"
4.5.3. include and extend
2.3.0 :005 > class C4 2.3.0 :006?> include M4 2.3.0 :007?> extend M4 2.3.0 :008?> end => C4 2.3.0 :009 > C4.method1 => 1 2.3.0 :010 > C4.new.method1 => 1
4.6. Scope of methods, attributes
Definition
- public: can called in every where → this is default
- protected: can called only inside object, instance of sub class
- private: can called only inside object
class Bar1 def public_method1; 1; end public def public_method2; 2; end protected def protected_method1; 1; end def protected_method2; 2; end private def private_method1; 1; end end Bar1.new.public_method1 → 1 Bar1.new.public_method2 → 2 Bar1.new.protected_method1 → NoMethodError Bar1.new.protected_method2 → NoMethodError Bar1.new.private_method1 → NoMethodError
- We can change the scope of method or attributes by using key word: public, private, protected like below:
class Bar1 def public_method1; 1; end public def public_method2; 2; end protected def protected_method1; 1; end def protected_method2; 2; end private def private_method1; 1; end end class Bar2 < Bar1 public :private_method1 end Bar2.new.private_method1 → 1
★ NOTE: Can not use self for calling a private method inside object
class Bar2 def public_method1 private_method1 end def public_method2 self.private_method1 end private def private_method1; 1; end end b = Bar2.new b.public_method1 → 1 b.public_method2 → NoMethodError: private method `private_method1' called for #<Bar2:0x007fc3ca806a70>
4.6.2. Kernel module and function
- Object class is including Kernel module
2.3.0 :052 > Object.included_modules => [Kernel]
- In Kernel, there are some methods are defined, sample: p, puts. You can check all methods of Kernel module by run: Kernel.methods
- Almost methods of Kernel module are private, so we can not call them with self
puts "a" → this is ok self.puts "a" → NoMethodError
NOTE: When you defined a method inside irb, that method will be a method of Object class.
This means all other classes (what are an instance of Object) can use this method.
2.3.0 :056 > self => main 2.3.0 :057 > def my_func; 1; end => :my_func 2.3.0 :058 > Integer.my_func => 1 2.3.0 :059 > String.my_func => 1 2.3.0 :060 > "a".my_func => 1
4.7. Variables and Constants
4.7.1. Local variables and global variables
- Local variables
2.3.0 :061 > v1 = 1 => 1 2.3.0 :062 > class Bar 2.3.0 :063?> p v1 2.3.0 :064?> end NameError: undefined local variable or method `v1' for Bar:Class
→ In above sample, we can not define class Bar because when defining it, we call variable v1.
v1 is defined in main but it can not be used inside other scope.
Other sample:
v1 = 1 class Bar2 v2 = 2 def method1; v1; end def method2; v2; end end b = Bar2.new b.method1 → NoMethodError: undefined local variable or method `v1' for #<Bar2:0x007fc3ca1ea268> b.method2 → NoMethodError: undefined local variable or method `v2' for #<Bar2:0x007fc3ca1ea268>
- Global variables: add $ as the first character when define variable name
$v1 = 1 class Bar2 $v2 = 2 def method1; $v1; end def method2; $v2; end end b = Bar2.new b.method1 → 1 b.method2 → 2
4.7.2. Instance variable
- Use prefix @ when define variable name
- Default is nil when variable is not initialized
@v1 = 1 class Bar @v2 = 2 def method1; @v1; end def method2; @v2; end end b = Bar.new b.method1 → nil b.method2 → nil class Bar2 def initialize; @v3 = 3; end def method3; @v3; end end Bar2.new.method3 → 3
- Auto generate getter, setter methods for instance variable by using attr_reader, attr_writer, attr_accessor, attr
Keyword | Meaning |
---|---|
attr_reader | Generate only setter method |
attr_writer | Generate only getter method |
attr_accessor | Generate both setter and getter |
attr | Generate only getter |
class B attr :var def initialize @var = 2 end end b = B.new b.var = 2 b.var
4.7.3. Class variables
- Use prefix @@ when define variable name
- Raise error when called uninitizalized variable
class Bar @@v1 = 1 def v1; @@v1; end def v2; @@v2; end end b = Bar.new b.v1 → 1 b.v2 → NameError class Bar2 < Bar def new_v1; @@v1; end end b2 = Bar2.new b2.new_v1 → 1
4.7.4. Nested scope of constants
- In previous part, we investigated about Constant.
A = 1 p A → 1 A = 2 → warning p A → 2
- Constant can be not defined inside method
def func B = 1 end → SyntaxError: dynamic constant assignment
- Nested scope of constants
- Normaly
module B; end B::A = 1 → Ok B::A::A = 1 → TypeError
- Modulized
module M A = 1 class B A = 2 end class C end end M::A → 1 M::B::A → 2 M.constants → [:A, :B, :C] M::B.constants → [:A]
- const_missing
module M def self.const_missing(id) id end end M::UNEXISTED_CONSTANT → :UNEXISTED_CONSTANT