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

    Chapter 4: Object orientation (continue)

    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
    

    Nguồn: Kipalog


Hãy đăng nhập để trả lời
 

Có vẻ như bạn đã mất kết nối tới LaptrinhX, vui lòng đợi một lúc để chúng tôi thử kết nối lại.