로그'메타프로그램 루비 버전 2'4장 읽기

제 4 장 수요일: 블록


개시하다

  • 블록이란 역할 영역을 제어하는 데 사용되는 강력한 도구
  • 블록은'호출 대상'대가족의 일원
  • 블록의 가정은 대상을 대상으로 하는 것과 달리'함수 프로그래밍 언어'의 절차
  • 블록의 기본

  • 호출 방법에서만 블록을 정의할 수 있습니다.
  • def a_method(a,b)
        a + yield(a,b)
    end
    
    a_method(1,2){ |x, y|(x + y) *3 }
    #=> 10
    
  • 메소드 내부에서 Kernel#blockgiven?사용 방법으로 블록 유무를 확인할 수 있음
  • def a_method
        return yield if block_given
        'ブロックがありません'
    end
    
    a_method #=> "ブロックがありません
    a_method { "ブロックがあるよ!" } #=> "ブロックがあるよ!"
    

    블록 닫기

  • 블록의 코드를 실행하기 위해서는 환경(로컬 변수/실례 변수/self)이 필요합니다.
  • 이러한 객체에 링크된 이름을 구속조건
  • 이라고 합니다.
  • 블록은 코드와 제약 집합을 포함한다
  • 블록을 정의한 경우 해당 점에 구속이 적용됩니다.
  • 블록을 방법에 전달할 때 그 속박도 함께 가져간다
  • def my_method
        x = "Goodbye"
        yield("cruel")
    end
    
    x = "Hello"
    my_method{ |y| "#{x}, #{y} world" } #=> "Hello, cruel world"
    
  • 블록에서도 새 구속조건을 정의할 수 있습니다.
  • 블록이 끝날 때 사라짐
  • def just_yield
        yield
    end
    
    top_level_variable = 1
    
    just_yield do
        top_level_variable += 1
        local_to_block = 1
    end
    
    top_level_variable #=> 2
    local_to_block #=> Error !
    

  • 덩어리가 현지의 속박을 감싸서 함께 가져가기 때문에 덩어리는 벽장이다
  • 역할 영역

  • 프로그램이 범위를 바꾸면 새로운 속박으로 바뀐다
  • 일반적인 상황에서 작용 범위에 변화가 발생하면 작용 범위를 속박한다
  • 작용문

  • 프로그램이 역할 영역을 전환하고 새로운 역할 영역을 열 위치
  • 클래스 정의
  • 모듈 정의
  • 방법
  • 프로그램 출입 클래스나 모듈의 정의나 방법에 따라 범위가 변한다
  • 경계선은class,module,def 같은 키워드로 표시
  • v1 = 1
    class MyClass #スコープゲート: classの入り口
        v2 = 2
        local_variables             #=> ["v2"]
        def my_method               # スコープゲート: defの入り口
            v3 = 3
            local_variables
        end                                     # スコープゲート: defの出口
        local_variables             #=> ["v2"]
    end
    
    obj = MyClass.new
    obj.my_method                       #=> [:v3]
    local_variables                 #=> [:v1, :obj]
    
  • 클래스나 모듈이 정의한 코드를 즉시 실행하지만 방법이 정의한 코드는 호출 방법에서 실행
  • 배열 역할 영역

  • 작용문을 통해 로컬 변수를 휴대
  • class의 경우

  • Class.new
  • 사용
    my_var = "成功"
    
    MyClass = Class.new do
        puts "クラス定義の中は#{my_var} !"
    
        def my_method
            ...
        end
    end
    

    def의 경우

  • define_method
  • 사용
    my_var = "成功"
    
    MyClass = Class.new do
        puts "クラス定義の中は #{my_var}!"
    
        define_method :my_method do
            "メソッド定義の中も #{my_var}!"
        end
    end
    

    평형기

  • 두 범위를 한 장소로 밀어넣고 변수를 공유하는 마술
  • '작용역의 평탄화'/'중첩구조의 에폭시(정태) 작용역'
  • 공유 역할 영역

  • 변수를 여러 방법으로 공유하고 싶지만 다른 방법으로는 볼 수 없음
  • 모든 방법을 같은 평형기로 정의하면 된다
  • 그러나 공유 범위를 실제로 사용하지 않음
  • def define_methods
        shared = 0
    
        Kernel.send :define_method, :counter do
            shared
        end
    
        Kernel.send :define_method, :inc do |x|
            shared += x
        end
    end
    
    define_methods
    
    counter
    inc(4)
    counter
    
  • 작용역문, 평면경, 공유경을 조합하면 작용역을 자유롭게 구부릴 수 있고 좋아하는 곳에서 필요한 변수를 볼 수 있다
  • 컬렉션 요약


    작용문

  • class/module/def
  • 옷장

  • 청크
  • 정의 블록은 현재 환경의 제약 패키지를 그 안에 넣고 휴대할 수 있다
  • 평형기

  • classClass.new/moduleModule.new/defModule.define_method교체 가능
  • 공유 역할 영역

  • 같은 평면경에서 여러 가지 방법을 정의하고 작용문에서 보호
  • instance_eval

  • instance_eval에 전달된 블록은 수신기가self로 설정된 후에 평가되기 때문에 수신기의privte 방법과 @v 같은 실례 변수에 접근할 수 있습니다
  • Instance_eval에 건네주는 블록을 상하문 탐지기
  • 라고 부른다.
    class MyClass
        def initialize
            @v = 1
        end
    end
    
    obj = MyClass.new
    
    obj.instance_eval do
        self        #=> #<MyClass:0x3340dc @v=1>
        @v          #=> 1
    end
    
  • 상하문 탐지기를 사용하면 봉인을 파괴할 수 있다
  • irb에서 대상 내용을 보고 싶을 때 instanceeval로 대상에 들어가는 것이 지름길
  • 블록만 평가하기 위해 생성된 대상을 청결실이라고 한다
  • BasicObject 실례는 먼지 없는 방으로 가장 적합
  • 호출 가능 대상

  • 블록의 사용은 두 과정으로 나뉜다
  • 코드 저장
  • (yeld 사용) 후 호출
  • 루비를 통해 코드를 보관할 수 있는 곳

  • 프로세스 중입니다.이것은 블록을 대상으로 하는 물체

  • Lambda에서Proc의 변형

  • 방법 중.
  • Plco 객체

  • 블록은 객체가 아닙니다

  • Proc는 블록을 대상으로 합니다.
  • Proc를 생성하기 위해 블록을 Proc.new
  • 에 전달
  • 나중에 대상이 되는 블록을 평가하기 위해 Proce#call을 호출
  • inc = Proc.new{ |x| x + 1 }
    inc.call(2) #=> 3
    
  • 프로세스를 생성하는 방법
  • lambda/proc
  • dec = lamda{|x| x-1 }
    dec.class #=> Proc
    dec.call(2) #=> 1
    

    Proc 쌍 lambda

  • lambda로 제작된 Proc는 다른 Proc와 달리 lambda
  • 로 불린다
  • Proc와 lambda의 차이점
  • return 키워드
  • 매개 변수에 대한 검사
  • 도대체 뭘 쓰면 좋을까요?
  • Proc 기능이 필요하지 않으면 우선 lambda
  • 를 선택합니다.

    Method 객체

  • Object#method를 호출할 때 방법 자체를 Method 대상으로 가져올 수 있음
  • class MyClass
        def initialize(value)
            @x = value
        end
    
        def my_method
            @x
        end
    end
    
    object = MyClass.new(1)
    m = object.method :my_method
    m.call #=> 1
    
  • Method 객체는 블록이나 lambda와 유사합니다.
  • 정의된 범위를 통해 lambda를 평가하지만 소속 대상의 범위를 통해 Method
  • 를 평가한다.

    호출 가능 객체 병합

  • 블록
  • 정의된 범위를 통해 평가
  • Proc
  • Proc 클래스의 객체블록의 경우 정의된 범위로 평가
  • lambda
  • Proc류의 대상이지만 일반적인 Proc와는 미묘하게 다르다.블록 또는 Proc와 동일한 클론으로 정의된 범위 평가
  • 방법
  • 대상을 결합하고 대상의 범위를 통해 평가한다
  • 대상의 범위와 분리하고 대상을 다른 대상과 결합시킬 수 있다.
  • 감상


    응, 드디어 정리했어...
    조금, 이 장의 이해는 전체 장과 비교하면 비교적 약하다...
    네모난 덩어리가 뭔지 궁금하네.익숙하지 않다
    TODO: 비워둔 시간 다시 읽기

    좋은 웹페이지 즐겨찾기