【问题标题】:Ruby: No Block Given errorRuby:没有块给定错误
【发布时间】:2011-04-03 08:50:17
【问题描述】:

在尝试将字符串传递给 is_tut 时,我不断收到“没有给出块”错误?方法。我是 Ruby 新手,不知道我做错了什么。任何和所有的帮助将不胜感激。

class Tut
@@consonants = ["b","c","d","f","g","h","j","k","l","m","n","p","q","r","s","t","v","w","x","y","z"]

  def is_tut? string
    if string =~ /^(([b-df-hj-np-z]ut)|([aeiou\s])|[[:punct:]])+$/i
      yield
    else
      false
    end
  end

  def self.to_tut string 
        string.each_char do |c|
            c += "ut" if @@consonants.find { |i| i == c.downcase }
            yield c
        end
    end

    def self.to_english string
        array = string.split //
        array.each do |c|
            if @@consonants.find { |i| i == c.downcase }
                array.shift
                array.shift
            end
            yield c
        end
    end


end

#Tut.to_tut( "Wow! Look at this get converted to Tut!" ) { |c| print c }
# should output : Wutowut! Lutookut atut tuthutisut gutetut cutonutvuteruttutedut tuto Tututut!

puts
puts

tut = Tut.to_tut( "Wow! Look at this get converted to Tut!" )
puts "from return: #{tut}"

puts

#Tut.to_tut( "Wutowut! Lutookut atut tuthutisut gutetut cutonutvuteruttutedut tuto Tututut!" ) { |c| print c }
# should outout : Wutowut! Lutookut atut tuthutisut gutetut cutonutvuteruttutedut tuto Tututut!
puts
puts

#tut = Tut.to_tut( "Wutowut! Lutookut atut tuthutisut gutetut cutonutvuteruttutedut tuto Tututut!" )
#puts "from return: #{tut}"

puts

#tut_string = ""
#Tut.to_tut( "I'm in tut but I want to be in english." ) { |c| tut_string += c }
#puts tut_string
# should output : I'mut inut tututut bututut I wutanuttut tuto bute inut enutgutlutisuthut.

puts

#Tut.to_english( tut_string ) { |c| print c }
# should output : I'm in tut but I want to be in english.

【问题讨论】:

  • 作为提示,定义辅音的更 Ruby 风格的方法是:@@consonants = ('a' .. 'z').to_a - %w[a e i o u]
  • 在 Ruby 中,缩进通常是两个空格。
  • 它在 Textmate 中看起来正确,但认为它没有正确粘贴。

标签: ruby


【解决方案1】:

如果您的方法定义中有yield,这意味着您必须在使用它时强制传递一个块(除非包含它的部分没有根据条件等执行)。 (您可能已经知道,但万一您不知道:块是被描述为{...}do ... end 的东西)而yield 将引用块。

如果您想让一个块可选,那么一种方法是在变量名之前放置& 符号。

def method(argument, &block_argument)
   if block_argument # block is given
      block_argument.call(argument_for_block) # use call to execute the block
   else # the value of block_argument becomes nil if you didn't give a block
      # block was not given
   end
end

这将允许可选块。或者,正如 Squeegy 所建议的,

def method(argument)
   if block_given? # block is given
      yield(argument_for_block) # no need to use call to execute the block
   else 
      # block was not given
   end
end

也可以。

【讨论】:

  • 或者你可以使用block_given? 来代替yield if block_given?
  • 这是另一个好方法。 block_given检查是否有block,如果没有则返回false,yield不会被执行,也就是说不会出错。
【解决方案2】:

因为您在 to_tut() 方法中调用了 yield,所以该行将失败:

tut = Tut.to_tut( "Wow! Look at this get converted to Tut!" )

你要么需要阻止(就像你在第一次注释掉的Tut.to_tut()调用中所做的那样),或者你需要修改你的to_tut()函数make the code block optional:

def self.to_tut string 
    string.each_char do |c|
        c += "ut" if @@consonants.find { |i| i == c.downcase }
        yield c if block_given?
    end
end

【讨论】:

  • 甜!!那行得通!感谢大家!稍后我可能会带着更多问题回到这里。感谢您的帮助。
【解决方案3】:

yield 需要将一个块传递给to_tut

当你这样做时:

Tut.to_tut( "Wow! Look at this get converted to Tut!" ) { |c| print c }

因为它有 { |c| print c } 块,所以它可以工作。

如果没有块,它会引发错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-10
    • 2012-07-25
    • 1970-01-01
    • 1970-01-01
    • 2021-10-08
    • 2014-09-14
    • 2010-11-21
    • 2017-01-25
    相关资源
    最近更新 更多