2011-10-11 3 views
1

Ruby를 처음 사용했습니다. 나는 내가 다른 언어에서와 같이 루비에서 일을 성공적으로 시도하지 못한 단계에있다.Ruby에서 외부 범위의 변수에 액세스 할 수있는 방법을 객체에 추가하는 방법은 무엇입니까?

개체에 메서드를 추가하려고합니다. 즉, 겸손한 배열입니다. 모든 어레이가 아니라 하나의 특정 배열에. 이 메서드는 외부 범위의 변수에 액세스 할 수 있어야합니다.

내 생각에 def을 사용하여 개체에 메서드를 추가 할 수 있지만이 메서드는 외부 범위의 변수에 액세스 할 수 없습니다. 그 때문에 나는 lambda 또는 Proc.new을 사용할 필요가 있지만 어떻게 lambda/proc를 배열에 속성으로 "부착"하는지 알 수 없습니다.

var x = 3 
var array = [1, 2, 3, 4] 

array.multiply_by_x = function() { 
    var i = this.length 
    while (i--) { 
    this[i] *= x 
    } 
} 

루비 위의 가능한 유사한인가 :이 바보 예를 보여줍니다로서이, 간단 자바 스크립트에서

?

답변

4

당신은 데프 키워드를 사용할 수 없습니다 다른 스코프를 도입 할 것이므로 여기에서 메서드를 정의하십시오. 메서드를 특정 개체에만 정의하려면 singleton 클래스로 메서드를 정의해야합니다.

(class << array; self; end).send(:define_method, :multiply_by_x) do 
    self.map!{|e| e * x } 
end 

참고 : 그것은이 질문에 관련이없는,하지만 당신이 좋아하면 볼 different ways to define singleton methods.

당신이 루비에 1.8.x를 사용하는 경우

x = 3 
array = [1, 2, 3, 4] 

array.define_singleton_method(:multiply_by_x) do 
    self.map!{|e| e * x } 
end 

는, 당신은이 작업을 수행해야

+1

'singleton_class'는'ActiveSupport'에 정의되어 있으므로 바닐라 1.8에서는'(class << array; self; end) .send ...' – cam

+0

우수! 이것은 정확히 내가 한 것입니다. 이제 실제로 어떤 일을하는지, 그리고 왜'x'가이 경우에 접근 가능한지를 이해하기 위해 약간의 독서를해야합니다. – davidchambers

+0

@cam, 당신 말이 맞아요. 나는 혼란 스럽다. – Samnang

1

원숭이 패치 Array이 작업을 수행하지만, Array의 모든 인스턴스에 대해 작업을 수행합니다.

class Array 
    def multiply_by(x) 
    self.map! {|n| 
     n * x 
    } 
    end 
end 

임의의 방법으로 기존 객체에 원숭이 패치를하고 싶다면 실제로 가능하지 않다고 생각합니다. 당신이 할 수

한 가지를 사용하는 Hashlambda 로모그래퍼 :

x = 3 
hash = {:array => [1,2,3]} 
hash[:multiply_by] = lambda { 
    hash[:array].map! {|num| 
     num * x 
    } 
} 

그런 다음 호출하려는 multiply_by 람다과 같이 :

hash[:multiply_by].call 
+0

기존 오브젝트를 아주 쉽게 원숭이 패치 할 수 있습니다 :'a = []; def a.add_one; 셀프 << 1; 종료; p a.add_one' – steenslag

+0

@steenslag 와우, 정말 맛있습니다! –

0

차라리 그렇게 할 것 : 보조 노트로

ary = [1, 2, 3, 4] 

def ary.multyply_by(x) 
    self.map! {|e| e * x} 
end 

p ary.multyply_by 10 

, 기능 parame를 사용하는 것이 훨씬 낫다 높게 범위가 지정된 변수보다 스코프는 장애물이 아닌 충돌을 피할 수있는 방법입니다.