Ruby - возможно передать блок как параметр как фактический блок другой функции? - PullRequest
6 голосов
/ 18 марта 2010

Вот что я пытаюсь сделать:

def call_block(in_class = "String", &block)
    instance = eval("#{in_class}.new")
    puts "instance class: #{instance.class}"
    instance.instance_eval{ block.call }
end


# --- TEST EXAMPLE ---
# This outputs "class: String" every time
"sdlkfj".instance_eval {  puts "class: #{self.class}" }

# This will only output "class: Object" every time
# I'm trying to get this to output "class: String" though
call_block("String") { puts "class: #{self.class}" }

В строке, где написано "instance.instance_eval {block.call}", я пытаюсь найти другой способ заставить новую переменную экземпляра запускать экземпляр eval в блоке. Единственный способ заставить его сделать это - передать instance_eval оригинальный блок, не как переменную или что-то еще, а как реальный блок, как в тестовом примере.

Любые советы?

1 Ответ

9 голосов
/ 18 марта 2010

Да. Вы можете передать блок другому методу, добавив переменную блока с амперсандом, например:

def foo &blk
  # now, blk is a variable bound to a block object
  bar &blk
end

Причина, по которой вы получаете "class: Object", заключается в том, что Ruby использует лексическую область видимости. Это означает, что self в puts "class: #{self.class}" относится к main, контексту по умолчанию.

...