【问题标题】:block_given? always returns false [closed]块给定?总是返回 false [关闭]
【发布时间】:2016-12-06 21:28:54
【问题描述】:

所以我尝试在Ruby中编写method_missing,method_missing有三个参数,如图所示

def method_missing(mId,*args,&block)
     if (args.empty? && !block_given?)
          puts " Sample One  No arguments were given nor block"
      elsif (!args.entries.empty?)
          puts " there was arguments given"
      elsif (block_given?)
           puts "there was ?code given"
    end 
end 

调用 instance.anything { "block" } 的问题总是返回 " Sample One No arguments were given or block"。 很明显 block_given 总是返回 false ,但是为什么呢?

【问题讨论】:

  • 无法重现:Foo.new.anything {} # there was ?code given

标签: ruby-on-rails ruby


【解决方案1】:

您的方法中的逻辑有点过于复杂,这就是它无法按照您的期望工作的主要原因。 block_given?没有问题

另外,我看不出args.entries.empty? 的使用有任何原因。 args.empty? 给你同样的结果,但看起来更清晰。

原始方法可以像这样重写,但我会注意到您没有涵盖可以使用参数和块调用方法的情况。不知道是不是故意的。

def method_missing(mid, *args, &block)
  if args.count > 0
    puts "there were arguments found"
  else
    if block_given?
      puts "there was a code found"
    else
      puts "Sample One  No arguments were given nor block"
    end
  end
end   

哪个例子显示了block_given?正常工作:

class A
  def method_missing(mid, *args, &block)
    p block
    p block_given?
  end
end

A.new.aaaa
nil
false
 => false 

A.new.aaaa { "aaaa" }
#<Proc:0x007fabd313d090@(irb):8>
true
 => true  

【讨论】:

  • 当有一个空的 1-empty 参数、2-key-value 对已在参数中传递、3-块代码已传递时,我不想发生某些过程。考虑到在传递代码块时,会给出同样满足案例 1 的参数。
  • 如果要检查方法中是否传递了关键字参数,则使用双 splat 表示法将它们收集到一个变量中,然后引用这个 Hash 类型的变量。 method_missing(mid, *args, **kwargs, &block) flushentitypacket.github.io/ruby/2015/03/31/… stackoverflow.com/questions/18289152/…
【解决方案2】:

这个有点令人费解。

block_given 没有任何问题,除了您的检查嵌套在“if else”块中。 (太长了;没看摘要)

如果您没有将任何参数传递给您的函数,您只会看到“有代码给出”。传入参数会触发!args.entries.empty? if,如果匹配,则不会执行任何进一步的 else 语句。

(在家里试试这个:尝试在没有参数和块的情况下调用你的方法,然后使用参数和块)。

如果您的预期/期望输出是: there was arguments given there was ?code given

那就试试这个方法吧。请注意我是如何让您的最后一个 elsif 成为一个普通的 if 声明:

def method_missing(mId,*args,&block) if (args.empty? && !block_given?) puts " Sample One No arguments were given nor block" elsif (!args.entries.empty?) puts " there was arguments given" end if (block_given?) puts "there was ?code given" end
end

【讨论】:

  • 在问题的最后一行,OP写道调用instance.anything { " block" },即没有参数但有一个块也不起作用,这与你的解释不符。跨度>
  • 没有工作它执行也放了“示例一没有给出参数也没有阻止”
猜你喜欢
  • 1970-01-01
  • 2020-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多