Ruby implementation of Soundex algorithm I'm new to Ruby. I normally sling code in C#. What could I do to make this simple Soundex class more Rubyesque?

class Surname
  attr_accessor :value

  def initialize(input)
    @value = input
  end

  def soundex
    result = ''
    @value.chars.drop(1).each do |s|
      number = soundex_value(s).to_s
      result &amp;lt;&amp;lt; number unless result[-1,1] == number
    end
    @value.chars.first &amp;lt;&amp;lt; result.ljust(3,'0')
  end

  def soundex_value(s)
    case s
    when /[bfpv]/
      1
    when /[cgjkqsxz]/ 
      2
    when /[dt]/ 
      3
    when /l/ 
      4
    when /[mn]/ 
      5
    when /r/ 
      6
    else ''
    end
  end
end

def print_name(input)
  surname = Surname.new(input)
  puts(surname.value + ' =&gt; ' + surname.soundex)
end

['Smith', 'Johnson', 'Williams', 'Jones', 'Brown'].each do |s|
  print_name s
end


The output is: 


Smith => S530
Johnson => J525
Williams => W452
Jones => J520
Brown => B650
Per your request, your code converted to the Ruby way perhaps would be as follows.

A small point: in our output, in the Ruby world, we would avoid the => fat comma which Rubyists (at least in the English-speaking world) call a 'hash-rocket' because:


It reads like Ruby's (older) hash accessing syntax.
In Ruby language documentation (e.g., see Array), the similar #=>, comprising a hash to introduce a comment, followed by a hash-rocket (presumably, this gave us the name), shows us the result (or value) of an individual line of code—the two meanings conflict.


BTW, we also would avoid ->, dash-greater-than, which in Ruby (syntax) generates a lambda.


class Soundex &lt; String
  IGNORED_BEGINNING_LENGTH = 1
  MINIMUM_LENGTH = 3

  CASES = [ # Keep order.
    /[bfpv]/,
    /[cgjkqsxz]/,
    /[dt]/,
    /l/,
    /[mn]/,
    /r/,
  ]
  CASES_LENGTH = CASES.length

  def initialize(surname)
    a = surname.split ''
    kept    = a.take(IGNORED_BEGINNING_LENGTH).join ''
    indices = a.drop(IGNORED_BEGINNING_LENGTH).map do |e|
      (0...CASES_LENGTH).detect{|i| e =~ (CASES.at i)}
    end.compact
# Adjust to one-based notation; collapse repetition; right-pad with zeros.
    digits = indices.map(&amp;:succ).join('').squeeze.ljust MINIMUM_LENGTH, '0'
    super kept + digits
  end

  def self.show(s) "#{s}: #{new s}" end
end

names = %w[Smith Johnson Williams Jones Brown Atchison]
names.each{|s| puts Soundex.show s}


gives the results


Smith: S530
Johnson: J525
Williams: W452
Jones: J520
Brown: B650
Atchison: A325