我试图在没有块的情况下调用此代码。底部的未注释线是我想要返回的。第一个未注释的行应该返回tut,第二行转换为英语,最后一行应该是英语。为什么“put eng”这条线上下而不是以句子形式返回?感谢您的帮助。
这是我的代码:
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 if block_given?
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 if block_given?
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.
lan = Tut.to_english( tut )
puts lan
答案 0 :(得分:0)
方法to_tut
和to_english
在没有阻止的情况下使用时会给出错误答案。发生这种情况是因为ruby始终返回方法中评估的最后一个值。在您的代码中,string.each_char
为to_tut
或array.each
为to_english
的结果。在这两种情况下,结果都包含原始输入,因此返回并打印。
对于puts eng
,它会打印由array.each
to_english
返回的数组。
答案 1 :(得分:0)
(打开注释:您通常不希望在迭代时修改Enumerable对象,因为这会使读取代码并调试它变得更加困难。)
你的to_tut不会保留你的修改,因为“c”块变量是字符串切片的副本,而不是对字符串部分的引用(如果它是ref,你可以使用< ;<要追加;“+ =”仍然无效,因为它重新分配而不是更改引用)。这就是each_char的工作原理,因为String不包含引用。
如果你想修改字符串,你可能需要向后计数,然后通过字符串#[] =插入'ut'。但这很复杂,所以我会提出几个替补。
工作to_tut#1:
def self.to_tut string
string.chars.map do |c|
yield c if block_given?
# this must be the last expression the block
if @@consonants.find { |i| i == c.downcase }
c + 'ut'
else
c
end
end.join
end
工作to_tut#2 - 这可能是最红宝石的方式:
def self.to_tut string
string.gsub(/[#{@@consonants.join}]/i) {|match|
yield match if block_given?
# this must be the last expression in the block
match + 'ut'
}
end
你的to_english不起作用,因为array.shift总是删除数组的第一个元素。相反,您希望跟踪当前索引,并从索引+ 1开始删除2个字符。
work to_english:
def self.to_english2 string
array = string.split //
array.each_with_index do |c, idx|
if @@consonants.find { |i| i == c.downcase }
array.slice!(idx+1, 2)
end
yield c if block_given?
end
array.join
end
关于为什么你的“put lan”每行返回一个char - 这是因为你的to_english返回一个数组。你想要调用join来转换它。