메타-3장-방법

16287 단어 Ruby

동적 디스크

  • method 이름이 매개 변수이기 때문에 실행할 때method
  • 를 확정합니다
  • 동적 호출
  • class MyClass
        def my_method(my_arg)
            my_arg * 2
        end
    end
    
    obj = MyClass.new
    obj.my_method(3)
    # 6
    obj.send(:my_method, 3)
    # 6
    

    동적method

  • define_method를 사용할 때, method를 실행할 때 method의 이름을 정합니다
  • 동적 정의
  • class MyClass
        define_method :my_method do |my_arg|
            my_arg * 3
        end
    end
    
    obj = MyClass.new
    obj.my_method(2)
    

    팩시밀리


    original code

    class Computer
        def initialize(computer_id, data_source)
            @id = computer_id
            @data_source = data_source
        end
    
        def mouse
            info = @data_source.get_mouse_info(@id)
            price = @data_source.get_mouse_price(@id)
            info = "Mouse: #{info} (#{price})"
            return "* #{result}" if price >= 100
            result
        end
    
        def cpu
            info = @data_source.get_cpu_info(@id)
            price = @data_source.get_cpu_price(@id)
            info = "Mouse: #{info} (#{price})"
            return "* #{result}" if price >= 100
            result
        end
    
        def keyboard
            info = @data_source.get_keyboard_info(@id)
            price = @data_source.get_keyboard_price(@id)
            info = "Mouse: #{info} (#{price})"
            return "* #{result}" if price >= 100
            result
        end
    end
    

    동적 디스크 응용 프로그램

  • send를 사용하여method
  • 를 동적 호출
  • @data_source.send "get_#{name}_info" , @id
  • class Computer
        def initialize(computer_id, data_source)
            @id = computer_id
            @data_source = data_source
        end
    
        def mouse
            component :mouse
        end
    
        def cpu
            component :cpu
        end
    
        def keyboard
            component :keyboard
        end 
    
        def component(name)
            info = @data_source.send "get_#{name}_info" , @id
            price = @data_source.send "get_#{name}_price", @id
            info = "#{name.capitalize}: #{info} (#{price})"
            return "* #{result}" if price >= 100
            result
        end
    end
    

    동적 method 사용

    class Computer
        def initialize(computer_id, data_source)
            @id = computer_id
            @data_source = data_source
        end
    
        def self.define_component(name)
            define_method(name) do
                info = @data_source.send "get_#{name}_info" , @id
                price = @data_source.send "get_#{name}_price", @id
                info = "#{name.capitalize}: #{info} (#{price})"
                return "* #{result}" if price >= 100
                result
            end
        end
    
        define_component :mouse
        define_component :cpu
        define_component :keyboard
    end
    

    한결

  • 블록을 String#grep에 전달하면 정규 표현식과 일치하는 요소에 대해 블록
  • 을 실행합니다
  • 정규 표현식에 일치하는 문자열을 $1에 저장
  • class Computer
        def initialize(computer_id, data_source)
            @id = computer_id
            @data_source = data_source
            data_source.methods.grep(/^get_(.*)_info$/) { Computer.define_component $1 }
        end
    
        def self.define_computer(name)
            define_method(name) do
                info = @data_source.send "get_#{name}_info", @id
                price = @data_source.send "get_#{name}_price", @id
                result = "#{name.capitalize}: #{info} (#{price})"
                return "#{result}" if price >= 100
                result
            end
        end
    end
    

    유령 방법

  • 항상 슈퍼
  • 를 호출합니다
  • 시종respondmethod_missing?
  • 진정한 방법이 아니다
  • 중도 포착 방법만 호출
  • 행동거지가 실제 방법과 다르다
  • Object#method 결과 일람표에 없음
  • 방법 호출이 대량으로 존재하거나 실행할 때만 호출 방법을 알 수 있는 상황에서 사용
  • 동적 방법

  • 일반 방법
  • def 대신 define-method에서 정의된 부분만 다르다

    동적 방법을 사용한 팩스

    class Computer
      def initialize(computer_id, data_source)
        @id = computer_id
        @data_source = data_source
        data_source.methods.grep(/^get_(.*)_info$/) { Computer.define_component $1 }
      end
    
      def self.define_component(name)
        define_method(name) do
          info = @data_source.get_keyboard_info(@id)
          price = @data_source.get_keyboard_price(@id)
          result = "keyboard: #{info} ($#{price})"
          price >= 100 ? "* #{result}" : result
        end
      end
    end
    

    Computer 클래스를 method로 설정팩스로

    class Computer
      def initialize(computer_id, data_source)
        @id = computer_id
        @data_source = data_source
      end
    
      def method_missing(name)
        super if !@data_source.respond_to?("get_#{name}_info")
        info = @data_source.send("get_#{name}_info", @id)
        price = @data_source.send("get_#{name}_price", @id)
        result = "#{name.capitalize}: #{info} ($#{price})"
        price >= 100 ? "* #{result}" : result
      end
    
      def respond_to_missing?(method, include_private = false)
        @data_source.respond_to?("get_#{method}_info") || super
      end
    end
    

    좋은 웹페이지 즐겨찾기