Meta-2 장 - 객체 모델

16627 단어 Ruby

개방 클래스

  • 표준 클래스에method
  • 추가 가능
    require 'test/unit'
    
    def to_alphanumeric(s)
        s.gsub /[^\w\s]/, '' # [a-zA-Z0-9_空白]以外
    end
    
    class ToAlphanumericTest < Test::Unit::TestCase
        def test_steps_non_alphanumeric_characters
            assert_equal '3 the Magic Number', to_alphanumeric('#3, the ***Magic, Number*?')
        end
    end
    
    require 'test/unit'
    
    class String
        def to_alphanumeric
            gsub /[^\w\s]/, ''
        end
    end
    
    class ToAlphanumericTest < Test::Unit::TestCase
        def test_steps_non_alphanumeric_characters
            assert_equal '3 the Magic Number', '#3, the ***Magic, Number*?'.to_alphanumeric
        end
    end
    
  • method 검색
  • [].methods.grep /^re/
    # [:repeated_permutation, :repeated_combination, :reject, :reverse_each, :replace, :reverse, :reverse!, :reject!, :reduce, :remove_instance_variable, :respond_to?]
    
    "".methods.grep /^re/
    [:replace, :reverse, :reverse!, :remove_instance_variable, :respond_to?]
    

    Object 및 instance 변수

  • object의 instance 변수는 object(@v는 각각의 object에 있음)
  • object의method는class(mymethod는MyClass)
  • instance 변수는 값이 대입될 때 처음 나타난다
  • class MyClass
        def my_method(v)
            @v = v
        end
    end
    
    obj1 = MyClass.new.my_method(5)
    obj2 = MyClass.new.my_method(7)
    obj3 = MyClass.new
    obj3.instance_variables 
    # []
    obj3.my_method
    obj3.instance_variables 
    # [:@v]
    

    대상은 instance 변수와class에 대한 링크로 구성되어 있습니다


    대상의method는class에 산다.class로 봤을 때 instance method라고 불려요.


    class는 Class 클래스의 대상입니다.유명은 상수에 불과하다.


    Class는 Module의 하위 클래스입니다.

  • module:method의 총결산
  • class:new, 슈퍼클래스로 층구조
  • 제작

    module와class의 이름은 디렉터리입니다. 상수는 파일과 같은 느낌입니다

     module MyModule
         MyConstant = 'out 定数'
         class MyClass
             MyConstant = 'innner 定数'
         end
     end
    
    MyModule::MyConstant
    # "out 定数"
    MyModule::MyClass::MyConstant
    # "inner 定数"
    

    require, load method


    파일을 한 번만 읽기
    호출할 때마다 파일 실행하기
    require './a.rb'
    
    # loadは定数が変数を汚染する、防ぐためにtrueオプション
    load('a.rb', true)
    

    class에는 BasicObject에 대한 계승 체인이 있습니다


    method 탐색

  • 수신기류에 들어가 방법을 찾기 전에 상속체인
  • 상승
  • 수신기: obj.my_method 수신기obj 수신기
  • 계승체인: 슈퍼클래스를 따라 전진
  • class MyClass
        def my_method
            @v = 1
        end
    end
    
    class SubClass < MyClass
    end
    
    obj = SubClass.new
    obj.my_method
    SubClass.ancestors
    # SubClass, MyClass, Object, Kernel, BasicObject]
    

    class에 모듈을 넣습니다.

  • include의class 바로 위에 진입
  • prepend:prepend의class의 바로 아래
  • 에 들어갑니다
    module M1
        def my_method
            @v = 1
        end
    end
    
    class C 
        include M1
    end
    
    class C1
        prepend M1
    end
    
    class D < C
    end
    
    D.ancestors
    # [D, C, M1, Object, Kernel, BasicObject]
    
    class E < C1
    end
    
    E.ancestors
    # [E, M1, C1, Object, Kernel, BasicObject]
    
    

    만약 모듈이 체인에 포함되어 있다면, 두 번째 무시

  • M1-to-M3 prepend[M1, M3]
  • M3 중 M2는include[M1, M3, M2]
  • M1은 M2에서include이지만 M1은 이미 체인에 있기 때문에 무시
  • module M1; end
    module M2
        include M1
    end
    module M3
        prepend M1
        include M2
    end
    
    M3.ancestors
    # [M1, M3, M2]
    

    Kernel

  • 어디서든 printmethod를 호출할 수 있기 때문에 Object class include의 Kernel module
  • Kernel에 method를 추가하면 어디서나 사용할 수 있음
  • require 'awesome_print'
    
    local_time = { :city => "Roma", :now => Time.now }
    ap local_time, :indent => 2
    
    #{
    #  :city => "Roma",
    #   :now => 2017-03-29 21:32:45 +0900
    #}
    # awesome_printがKernelにap methodを追加している
    

    method를 호출할 때 수신기는self입니다

  • 코드는currentobject 내부(self)에서 실행
  • method를 호출할 때method의 수신기self
  • 그때부터 모든 instance 변수는self의 instance 변수이고 수신기가 지정되지 않은method 호출은self
  • 를 모두 호출합니다
  • 마지막에method 수신기가 되는object를 쫓으면 절차가 뚜렷하다
  • class MyClass
        def testing_self
            @var = 10
            my_method
            self
            puts @var
        end
    
        def my_method
            @var = @var + 1
        end
    end
    
    obj = MyClass.new
    obj.testing_self
    # #<MyClass:0x007f83542e7cd0 @var=11>
    # testing_selfを呼び出すとレシーバであるobjがselfになる
    # そのためinstance変数@varはobjのinstance変数となる
    # レシーバを明示していないmy_methodの呼び出しもobjに対するものとなる
    # my_method時もselfはobjなので@varはobjのinstance変数のまま
    # よって、@varは+1される
    

    최상위

  • 호출되거나 호출되지 않은method가 모두 되돌아올 때의self는main
  • 이다
    self # main
    self.class # Object
    

    Refinements

  • 클래스 코드에 패치를 주고 일반적인 방법으로 검색하는 느낌을 다시 쓴다
  • Refinements는 using 호출에서 파일이나 모듈의 정의가 끝날 때까지 유한한 부분에만 유효합니다
  • module StringExtensions
        refine String do
            def to_alphanumeric
                gsub(/[^\w\s]/, '')
            end
        end
    end
    
    "my *1st* refinement!".to_alphanumeric
    # NoMethodError
    using StringExtensions
    "my *1st* refinement!".to_alphanumeric
    # "my 1st refinement!"
    
    module StringExtensions
        refine String do
            def reverse
                "esrever"
            end
        end
    end
    
    module StringStuff
        using StringExtensions
        "my *1st* refinement!".reverse
        # "esrever"
    end
    
    "my *1st* refinement!".reverse
    # "!tnemenifer *ts1* ym"
    

    Doctement print를 실행하려는 경우

  • 그 중 하나의 print의 이름을 바꾸기
  • include의 순서 바꾸기
  • module Printable
        def print
            puts 1
        end 
        def prepare_cover
            puts 2
        end
    end
    
    module Document
        def print_to_screen
            prepare_cover # 2 Printableで発見
            format_for_screen # 3 Documentで発見
            print # 1
        end 
        def format_for_screen
            puts 3
        end 
        def print
            puts 4
        end
    end
    
    class Book
        include Document # Bookの真上に入る
        include Printable # Bookの真上に入る
        puts 5
    end
    
    # Book > Printable > Document > Object > Kernel > Basic Object
    
    
    b = Book.new
    b.print_to_screen
    # 5 2 3 1
    
    Book.ancestors
    # [Book, Printable, Document, Object, Kernel, 
    BasicObject]
    
    b.method(:print).owner
    # Printable
    

    Ctrl + L


    pry 화면 지우기

    좋은 웹페이지 즐겨찾기