Что-то вроде пусть в Ruby - PullRequest
2 голосов
/ 16 февраля 2011

Раньше я писал подобные выражения - с лексической областью действия.

Так что я пишу свои собственные (печально, но это не удастся с несколькими потоками):

# 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

Я ищу в Google такие конструкции (возможно, дополнительные определения блоков) для ruby, но не могу найти их. Может я что то потерял? Какие рубиновые люди используют в таких случаях?

PS: Извините за мой плохой английский, вы знаете.

UPD: Не могу привести пример использования:

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

выход:

2
1

Ответы [ 2 ]

4 голосов
/ 16 февраля 2011

Идея:

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

Чипинг с одним значением более явный, потому что вы называете переменную (и) в аргументах блока. Эта абстракция была названа as, pipe, into, scope, let, peg, ..., вы называете это, все то же самое:

class Object
  def as
    yield self
  end
end

sum = ["1", "2"].map(&:to_i).as { |x, y| x + y } #=> 3
2 голосов
/ 16 февраля 2011

Вы не можете указать значение, которое хотите инициализировать, но вы можете объявить переменную как явно локальную для этого блока:

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

В результате:

external value
1
2
3
external value
...