Skip to content

Commit

Permalink
minor changes to Masao's String patch: mirror Ruby 1.9 in that it thr…
Browse files Browse the repository at this point in the history
…ows a KeyError when named interpolation placeholder is missing, rename/reformat a few things
  • Loading branch information
Sven Fuchs committed Jul 8, 2009
1 parent 55c1357 commit bd9e8be
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 22 deletions.
42 changes: 20 additions & 22 deletions lib/i18n/string.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,25 @@
license terms as Ruby.
=end

class KeyError < Exception
def initialize(message = nil)
super(message || "key not found")
end
end

# Extension for String class. This feature is included in Ruby 1.9 or later but not occur TypeError.
#
# String#% method which accept "named argument". The translator can know
# the meaning of the msgids using "named argument" instead of %s/%d style.
class String
# For older ruby versions (such as ruby-1.8.5)
alias :bytesize :size unless instance_methods.find {|m| m.to_s == 'bytesize'}
alias :interpolate_without_ruby_19_syntax :% # :nodoc:

unless instance_methods.find {|m| m.to_s == 'bytesize'}
# For older ruby (such as ruby-1.8.5)
alias :bytesize :size
end

alias :_old_format_m :% # :nodoc:

PERCENT_MATCH_RE = Regexp.union(
/%%/,
/%\{(\w+)\}/,
/%<(\w+)>(.*?\d*\.?\d*[bBdiouxXeEfgGcps])/
INTERPOLATION_PATTERNS = Regexp.union(
/%%/,
/%\{(\w+)\}/,
/%<(\w+)>(.*?\d*\.?\d*[bBdiouxXeEfgGcps])/
)

# call-seq:
Expand Down Expand Up @@ -52,23 +54,19 @@ class String
# "%<age>d, %<weight>.1f" % {:age => 10, :weight => 43.4}
def %(args)
if args.kind_of?(Hash)
ret = dup
ret.gsub!(PERCENT_MATCH_RE) {|match|
dup.gsub(INTERPOLATION_PATTERNS) do |match|
if match == '%%'
'%'
elsif $1
key = $1.to_sym
args.has_key?(key) ? args[key] : match
elsif $2
key = $2.to_sym
args.has_key?(key) ? sprintf("%#{$3}", args[key]) : match
else
key = ($1 || $2).to_sym
raise KeyError unless args.has_key?(key)
$3 ? sprintf("%#{$3}", args[key]) : args[key]
end
}
ret
end
else
ret = gsub(/%([{<])/, '%%\1')
begin
ret._old_format_m(args)
ret.send :'interpolate_without_ruby_19_syntax', args
rescue ArgumentError => e
if $DEBUG
$stderr.puts " The string:#{ret}"
Expand Down
50 changes: 50 additions & 0 deletions test/string_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
require File.expand_path(File.dirname(__FILE__) + '/test_helper')

# thanks to Masao's String extensions these should work the same in
# Ruby 1.8 (patched) and Ruby 1.9 (native)

class I18nStringTest < Test::Unit::TestCase
define_method :"test: String interpolates a single argument" do
assert_equal "Masao", "%s" % "Masao"
end

define_method :"test: String interpolates an array argument" do
assert_equal "Masao Mutoh", "%s %s" % %w(Masao Mutoh)
end

define_method :"test: String interpolates a hash argument w/ named placeholders" do
assert_equal "Masao Mutoh", "%{first} %{last}" % { :first => 'Masao', :last => 'Mutoh' }
end

define_method :"test: String interpolates named placeholders with sprintf syntax" do
assert_equal "10, 43.4", "%<integer>d, %<float>.1f" % {:integer => 10, :float => 43.4}
end

define_method :"test: String interpolation raises an ArgumentError when the string has extra placeholders (Array)" do
assert_raises(ArgumentError) do # Ruby 1.9 msg: "too few arguments"
"%s %s" % %w(Masao)
end
end

define_method :"test: String interpolation raises a KeyError when the string has extra placeholders (Hash)" do
assert_raises(KeyError) do # Ruby 1.9 msg: "key not found"
"%{first} %{last}" % { :first => 'Masao' }
end
end

define_method :"test: String interpolation does not raise when passed extra values (Array)" do
assert_nothing_raised do
assert_equal "Masao", "%s" % %w(Masao Mutoh)
end
end

define_method :"test: String interpolation does not raise when passed extra values (Hash)" do
assert_nothing_raised do
assert_equal "Masao Mutoh", "%{first} %{last}" % { :first => 'Masao', :last => 'Mutoh', :salutation => 'Mr.' }
end
end

define_method :"test: % acts as escape character in String interpolation" do
assert_equal "%{first}", "%%{first}" % { :first => 'Masao' }
end
end

0 comments on commit bd9e8be

Please sign in to comment.