开发者

Ruby: Method return without a block

I am trying to make this code return when called without a block. The uncommented lines at the bottom is what I'm trying to get to return. The first uncommented line should return in tut, second line converted to english and the last should be in english. And why is the line " puts eng " returning up and down and not in sentence form? Thanks for any and all help.

Here's my code:

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
开发者_开发百科


(Opening note: You normally don't want to modify an Enumerable object while iterating over it, since that makes it much harder to read the code and debug it.)

Your to_tut doesn't retain your modifications because the "c" block variable is a copy of the string slice, instead of a reference to part of the string (if it were a ref, you'd be able to use << to append; "+=" still wouldn't work because it reassigns rather than changing the ref). That's just how each_char works, since a String doesn't contain references.

If you wanted to modify the string in place, you'd probably have to count backwards and then insert the 'ut' by index via string#[]= . But that's way complicated so I'll present a couple alternates.

Working 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

Working to_tut #2 - this is probably the most ruby-ish way to do it:

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

Your to_english doesn't work because array.shift always removes the first element of the array. Instead, you want to track the current index, and remove 2 chars starting from index+1.

Working 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

Regarding why your "puts lan" returns one char per line - it's because your to_english returns an array. You'll want to call join to convert it.


The methods to_tut and to_english are giving you wrong answers when used without a block. This happens because ruby always returns the last value evaluated in your method. In your code that will be the result of the string.each_char for to_tut or array.each for to_english. In both cases, the result contains the original input, which is consequently returned and printed.

As to the puts eng, it prints the array returned by array.each of to_english.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜