2011-02-15 5 views
2

어휘 범위와 함께 let-like 표현을 쓰곤 했었습니다.Ruby에 들어있는 것과 비슷한 것

그래서 나는 (슬픈, 그러나 그것은 여러 스레드와 함께 실패합니다) 내 자신의 쓰기 :

# Useful thing for replacing a value of 
# variable only for one block of code. 
# Maybe such thing already exist, I just not found it. 
def with(dict, &block) 
    old_values = {} 

    # replace by new 
    dict.each_pair do |key, value| 
    key = "@#{key}" 
    old_values[key] = instance_variable_get key 
    instance_variable_set key, value 
    end 

    block.call 

    # replace by old 
    old_values.each_pair do |key, value| 
    instance_variable_set key, value 
    end 
end 

내가 루비와 같은 구조물 (아마도 추가적인 블록 정의)에 대한 구글에서 검색,하지만 그것을 발견 할 수 . 어쩌면 내가 느슨해 졌을 까? 루비 사람들이 그런 경우에 사용하는 것은 무엇입니까?

추신 : 내 나쁜 영어로 죄송합니다.

UPD : 내가 사용의 예를 제공하기 위해 foget :

@inst_var = 1 
with :inst_var => 2 do 
    puts @inst_var 
end 
puts @inst_var 

출력 :

2 
1 
+0

이하자 같은 표현은 무엇입니까? –

+0

@Andrew : let-expressions은 여러 언어 (LISP, 하스켈, ML 등)로 사용됩니다. http://www.cs.cmu.edu/~rwh/introsml/core/decls.htm – tokland

답변

4

아이디어 : 자신이 발생합니다. 이 추상화는 pipeintoscopeletpeg는 ..., 당신은 그것을 이름을 as 호출 된, 모든 동일합니다 :

class Object 
    def as 
    yield self 
    end 
end 

sum = ["1", "2"].map(&:to_i).as { |x, y| x + y } #=> 3 
+1

귀하의 필요에 따라 언어를 확장 할 수있는 두 가지 훌륭한 제안이 있습니다. – froginvasion

2

당신은 당신이 초기화 할 값을 지정할 수 없습니다,하지만 당신은을 선언 할 수 있습니다 변수를 해당 블록에 명시 적으로 로컬로 지정하십시오.

x = 'external value' 
puts x 
[1,2,3].each do |i; x| 
    x = i 
    puts x 
end 
puts x 

T 당신이 블록 인수의 변수 (들)의 이름 때문에

class Object 
    def let(namespace, &block) 
    namespace_struct = Struct.new(*namespace.keys).new(*namespace.values) 
    namespace_struct.instance_eval(&block) 
    end 
end 

message = let(language: "Lisp", year: "1958", creator: "John McCarthy") do 
    "#{language} was created by #{creator} in #{year}" 
end 

단일 값 scopping 더 명시 적입니다 :

external value 
1 
2 
3 
external value 
+0

'i'도이 예제에서 블록에 국한된다는 점은 주목할 가치가있다. – zetetic

관련 문제