所以我目前正在使用Ruby在优秀的CodeWars网站上进行培训,并且遇到了一个比我的水平高一点的问题,但如果我能看一下这个问题,我觉得它真的可以帮助我编写代码。 /答案并将它推到我的大脑周围一点。一种缺失的链接类型交易。
问题是如何构建Calc类以实现以下结果:
class Calc
end
Calc.new.one.plus.two # Should return 3
Calc.new.five.minus.six # Should return -1
Calc.new.seven.times.two # Should return 14
Calc.new.nine.divided_by.three # Should return 3
该类只需要处理单个数字输入零 - 九和+ - * /运算符,并且格式将始终是如上所示的3种方法的链(即数字运算符号)。
我很乐意阅读您的一些解决方案,如果您感到烦恼,那么您在解决它时会遇到的思考过程。谢谢!
答案 0 :(得分:1)
假设不会以无效的方式使用这些方法:
class Calc
def self.operand name, v
define_method(name) do
@operator ? @operand.send(@operator, v) : (@operand = v; self)
end
end
def self.operator name, v
define_method(name) do
@operator = v; self
end
end
operand :one, 1
operand :two, 2
...
operator :plus, :+
operator :minus, :-
...
end
答案 1 :(得分:1)
这个怎么样?
class Calc
attr_accessor :result, :last_operator
def initialize(result=0)
@result = result
end
OPERATORS = {
:plus => :+, :minus => :-, :times => :*, :divided_by => :/
}
OPERANDS = [ :zero, :one, :two, :three, :four, :five, :six, :seven, :eight, :nine, :ten, :eleven, :twelve ]
def method_missing(m, *args, &block)
if OPERATORS.include?(m.to_sym)
@last_operator = m.to_sym
return self
elsif OPERANDS.include?(m.to_sym)
if @last_operator.nil?
@result = OPERANDS.index(m.to_sym)
return self
end
@result = eval("#{@result} #{OPERATORS[@last_operator]} #{OPERANDS.index(m.to_sym)}")
return @last_operator.nil? ? self : @result
end
super
end
end
[20] pry(main)> Calc.new.three.times.seven
=> 21
[21] pry(main)> Calc.new.twelve.divided_by.two
=> 6
答案 2 :(得分:1)
不是最佳解决方案,但符合要求:
class Calc
ENGLISH_TO_OP = Hash[%i{zero one two three four five six seven eight nine}
.each_with_index.to_a].merge(plus: :+, minus: :-, times: :*, divided_by: :/)
def method_missing(m)
if s = ENGLISH_TO_OP[m]
(@cmd ||= []) << s
return @cmd[0].send(*@cmd[1..2]) if @cmd.size == 3
self
else
super
end
end
end
允许:
2.1.0 :015 > Calc.new.seven.times.two
=> 14
2.1.0 :016 > Calc.new.nine.divided_by.three
=> 3
2.1.0 :017 > Calc.new.five.minus.six
=> -1
2.1.0 :018 > Calc.new.one.plus.two
=> 3
我不想写很多代码,所以method_missing
必须要定义方法,即使它可能有问题,因此我倾向于避免它。哈希查找适用于指定的操作数和操作,each_with_index
可以填充值。在条件中将查找值分配给s只是懒惰。最后,我可以在初始值设定项中初始化@cmd
,但这样的代码更少,并且可以防止@cmd
稍后通过其他方法重置为nil。
答案 3 :(得分:0)
以下是使用#method_missing
的另一个技巧:
class Calc
attr_reader :val
def initialize
# operand hash
@hsh_num = {one: 1,two: 2, three: 3,four: 4,five: 5,six: 6}
# operator hash
@hsh_op = {plus: '+', minus: '-',times: '*',divided_by: '/'}
end
def method_missing(symbol)
if @hsh_num[symbol]
@val = @meth.is_a?(Method) ? @meth.call(@hsh_num[symbol]) : @hsh_num[symbol]
end
if @hsh_op[symbol]
@meth = @val.method(@hsh_op[symbol])
end
self
end
end
# I just added one more method val, to get the last output.
# a bit change I did.
Calc.new.one.plus.two.plus.two.val # => 3
Calc.new.five.minus.six.val # => -1
我没有为所有人实施它。但是,就你的情况而言,你可以从中得到一个想法。