ruby 对Sandi Metz的“Make Everything the same”博客文章进行冥想
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ruby 对Sandi Metz的“Make Everything the same”博客文章进行冥想相关的知识,希望对你有一定的参考价值。
## Sandi Metz's blog post:
[Make Everything The Same](http://www.sandimetz.com/blog/2016/6/9/make-everything-the-same)
Upon reading I decided to try an implement Sandi's concept before lookig at her code.
It wasn't worth a dime in comparison, but _after_ reading her code, I decided to try and improvise from there.
Of course, this is no more than remixing the composition from a genius to feel your own style on it. But it was a interesting exercise. I opted for a module with no state and pure functions.
I changed my naming towards hers for easier comparison. And I had to modify the test, to include reverse conversions, remove Minitest constant rename warnings, and call 'using' from the test instead of from the module as Sandi does, which does not work for me. (Any hints appreciated)
module Roman
refine Fixnum do
def to_roman
Numeral.i_to_r(self)
end
end
refine String do
def from_roman
Numeral.r_to_i(self)
end
end
module Numeral
extend self
def i_to_r(number)
to_subtractive(to_roman(number))
end
def r_to_i(string)
to_number(to_additive(string))
end
private
ROMAN_NUMERALS = {
1000 => 'M',
500 => 'D',
100 => 'C',
50 => 'L',
10 => 'X',
5 => 'V',
1 => 'I'
}.freeze
LONG_TO_SHORT_MAP = {
'DCCCC' => 'CM', # 900
'CCCC' => 'CD', # 400
'LXXXX' => 'XC', # 90
'XXXX' => 'XL', # 40
'VIIII' => 'IX', # 9
'IIII' => 'IV' # 4
}.freeze
def to_roman(number)
ROMAN_NUMERALS.inject('') do |converted, (value, letter)|
times, number = number.divmod(value)
converted << letter * times
end
end
def to_number(roman)
to_additive(roman).chars.reduce(0) do |total, letter|
total + ROMAN_NUMERALS.invert[letter]
end
end
def convert(map, string)
map.inject(string) do |out, (group, short)|
out.gsub(group, short)
end
end
def to_additive(string)
convert(LONG_TO_SHORT_MAP.invert, string)
end
def to_subtractive(string)
convert(LONG_TO_SHORT_MAP, string)
end
end
end
require 'minitest/autorun'
require_relative 'roman'
class RomanTest < MiniTest::Test
using Roman
def test_1
assert_equal 'I', 1.to_roman
assert_equal 'I'.from_roman, 1
end
def test_2
assert_equal 'II', 2.to_roman
assert_equal 'II'.from_roman, 2
end
def test_3
assert_equal 'III', 3.to_roman
assert_equal 'III'.from_roman, 3
end
def test_4
assert_equal 'IV', 4.to_roman
assert_equal 'IV'.from_roman, 4
end
def test_5
assert_equal 'V', 5.to_roman
assert_equal 'V'.from_roman, 5
end
def test_6
assert_equal 'VI', 6.to_roman
assert_equal 'VI'.from_roman, 6
end
def test_9
assert_equal 'IX', 9.to_roman
assert_equal 'IX'.from_roman, 9
end
def test_27
assert_equal 'XXVII', 27.to_roman
assert_equal 'XXVII'.from_roman, 27
end
def test_48
assert_equal 'XLVIII', 48.to_roman
assert_equal 'XLVIII'.from_roman, 48
end
def test_59
assert_equal 'LIX', 59.to_roman
assert_equal 'LIX'.from_roman, 59
end
def test_93
assert_equal 'XCIII', 93.to_roman
assert_equal 'XCIII'.from_roman, 93
end
def test_141
assert_equal 'CXLI', 141.to_roman
assert_equal 'CXLI'.from_roman, 141
end
def test_163
assert_equal 'CLXIII', 163.to_roman
assert_equal 'CLXIII'.from_roman, 163
end
def test_402
assert_equal 'CDII', 402.to_roman
assert_equal 'CDII'.from_roman, 402
end
def test_575
assert_equal 'DLXXV', 575.to_roman
assert_equal 'DLXXV'.from_roman, 575
end
def test_911
assert_equal 'CMXI', 911.to_roman
assert_equal 'CMXI'.from_roman, 911
end
def test_1024
assert_equal 'MXXIV', 1024.to_roman
assert_equal 'MXXIV'.from_roman, 1024
end
def test_3000
assert_equal 'MMM', 3000.to_roman
assert_equal 'MMM'.from_roman, 3000
end
end
以上是关于ruby 对Sandi Metz的“Make Everything the same”博客文章进行冥想的主要内容,如果未能解决你的问题,请参考以下文章