【问题标题】:Ruby: instance_exec with a block taking a block as parameterRuby:instance_exec,带有以块为参数的块
【发布时间】:2018-01-12 23:39:37
【问题描述】:

请考虑以下代码:

def a &block_a
    define_method :b do |&block_b|
        puts "Running in define_method"
        instance_exec block_a, &block_b
    end
end

a do
    puts "In block A"
end

b do |&block|
    puts "In block B"
    instance_eval &block
end

我希望将给方法“b”的块作为参数给定给方法“a”的块(b 是动态创建的)。 但是会返回以下输出/错误:

Running in define_method
In block B
wrong number of arguments (given 0, expected 1..3)
(repl):14:in `instance_eval'
(repl):14:in `block in <main>'
(repl):4:in `instance_exec'
(repl):4:in `block in a'
(repl):12:in `<main>'

“&block”似乎为零(尝试调用“block.call”而不是“instance_eval &block”会引发“block is nil”错误)。逻辑似乎很好,因为用字符串替换 'b' 块参数确实有效:

def a s
    define_method :b do |&block_b|
        puts "Running in define_method"
        instance_exec s, &block_b
    end
end

a "LOL"

b do |s|
    puts "In block B"
    puts s
end

感谢您的帮助!

【问题讨论】:

    标签: ruby


    【解决方案1】:

    很难理解你想要完成什么,我 102% 肯定你把事情复杂化了(阅读:做错了。)

    您的代码的问题是您迷失在块及其参数中。

    对于b 中的block 方法调用不是nilb 应该是yield,并且不允许产生块。可以显式调用该块,而不是让步:

    def a &block_a
      define_method :b do |&block_b|
      # ⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓
        block_b.(&block_a)
      end
    end
    
    a { puts "A" }
    
    b { |&block| puts "B"; instance_eval &block }
    

    另一种方式可能是接受b 中的普通参数,因为您传递的内容是block_a,这是一个普通的proc 实例:

    def a &block_a
      define_method :b do |&block_b|
        instance_exec block_a, &block_b
      end
    end
    
    a { puts "A" }
    
    #   ⇓⇓⇓⇓⇓⇓⇓
    b { |block| puts "B"; instance_eval &block }
    

    【讨论】:

    • 谢谢,看来我搞砸了 '&' 语法 :)。实际上这段代码将在一个类中运行并为其定义方法,所以我认为我需要“instance_eval”解决方案。
    • 我今天看到的每个 Ruby 问题似乎都有你的答案,旁边有一个√。
    猜你喜欢
    • 1970-01-01
    • 2011-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-06
    • 2019-12-04
    相关资源
    最近更新 更多