3

次のコードを想像してみてください。

class SimpleLetter
  def values
    ("a" .. "z").to_a
  end

  def ===(other)
    values.include?(other)
  end
end

class Vowel < SimpleLetter
  def values
    ["a","e","i","o","u"]
  end
end

class Consonant < SimpleLetter
  def values
    super - Vowel.new.values
  end
end

objects = ("a" .. "f").to_a + (1 .. 5).to_a

objects.each do |letter|
  case letter
    when Vowel.new
      puts "#{letter} it's a vowel"
    when Consonant.new
      puts "#{letter} it's a consonant"
    else
      puts "#{letter} it's something else"
  end
end

代わりに他のクラスを選択することもできます。例としてそれらを使用しています。私はScalamatchとエクストラクターが大好きで、これがRubyで同じことを書くための良い方法かもしれないと思いました。新しいオブジェクトをインスタンス化せずに上記を記述して、===メソッドを呼び出すことができるようにするためのより良い方法はありますか?

不必要な投稿を避けるために、はい、私はこれを行うことができることを知っています:

case letter
  when ["a","e","i","o","u"].include?(letter)
    # ...
end
4

5 に答える 5

5

キャラクターのクラスは必要ありません。それらを配列として設定し、caseステートメントでsplat演算子を使用します。

SimpleLetter = ("a" .. "z").to_a
Vowel        = %w[a e i o u]
Consonant    = SimpleLetter - Vowel

(("a" .. "f").to_a + (1 .. 5).to_a).each do |letter|
  case letter
    when *Vowel
      puts "#{letter} it's a vowel"
    when *Consonant
      puts "#{letter} it's a consonant"
    else
      puts "#{letter} it's something else"
  end
end
于 2011-05-23T20:04:01.223 に答える
4

===ブロックでも機能します:

Letters = ('a'..'z').to_a
Vowels = ['a','e','i','o','u']
Consonants = Letters - Vowels

Vowel = lambda { |x| Vowels.include? x }
Consonant = lambda { |x| Consonants.include? x }

objects = ("a" .. "f").to_a + (1 .. 5).to_a

objects.each do |object|
  case object
    when Vowel
      puts "#{object} is a vowel."
    when Consonant
      puts "#{object} is a consonant."
    else
      puts "#{object} is an object."
  end
end
于 2011-05-23T20:09:16.683 に答える
3

インスタンスメソッドの代わりにクラスメソッドを使用できます。

class SimpleLetter
    def self.values
        ("a" .. "z").to_a
    end 

    def self.===(other)
        values.include?(other)
    end 
end

class Vowel < SimpleLetter
    def self.values
        ["a","e","i","o","u"]
    end 
end

class Consonant < SimpleLetter
    def self.values
        super - Vowel.values
    end 
end

objects = ("a" .. "f").to_a + (1 .. 5).to_a

objects.each do |letter|

    case letter
        when Vowel
            puts "#{letter} it's a vowel"
        when Consonant
            puts "#{letter} it's a consonant"
        else
            puts "#{letter} it's something else"
    end 

end
于 2011-05-23T19:44:25.217 に答える
2

あなたが私を混乱させたコードはSimpleLetter、アルファベット全体ではなく、1文字でなければならないからです。

モンキーパッチは少し危険ですが、私は次のことをやろうと思っています。

module Voweliness
  def vowel?
    self =~ /[aeiou]/i
  end

  def consonant?
    (self =~ /[a-z]/i and not vowel?)
  end
end

class String
  include Voweliness
end


objects.each do |letter|
  case
    when letter.vowel?
      puts "#{letter} is a vowel"
    when letter.consonant?
      puts "#{letter} is a consonant"
    else
      puts "#{letter} is something else"
  end
end
于 2011-05-23T23:53:19.983 に答える
1

あなたはすでにいくつかの良い答え(例えばsawaの)を持っているので、私はcaseステートメントなしでただ楽しいものを含めています:

SIMPLE_LETTER = [*"a" .. "z"]
VOWEL        = %w[a e i o u]
CONSONANT    = SIMPLE_LETTER - VOWEL

[*?a..?f,*1..5].each do |letter|
  letter_class = %w(vowel consonant).select { |c| Object.const_get(c.upcase).include? letter}.first
  puts "'#{letter}': #{ letter_class || "something else"}"
end

出力:

'a': vowel
'b': consonant
'c': consonant
'd': consonant
'e': vowel
'f': consonant
'1': something else
'2': something else
'3': something else
'4': something else
'5': something else

マルチスプラットおよび文字リテラルは1.9でのみ機能します。

于 2011-05-23T21:40:23.863 に答える