vis*_*Bar 10 ruby methods ruby-on-rails method-chaining
我正在尝试为以下两种方法执行链接方法.运行此代码后,我不断获得以下输出:
#<SimpleMath:0x007fc85898ab70>%
Run Code Online (Sandbox Code Playgroud)
我的问题是:链接方法的正确方法是Ruby什么?
这是我的代码:
class SimpleMath
def add(a,b=0)
a + b
return self
end
def subtract(a,b=0)
a - b
return self
end
end
newNumber = SimpleMath.new()
print newNumber.add(2,3).add(2)
Run Code Online (Sandbox Code Playgroud)
Rus*_*nov 12
你想做这样的事吗?
class SimpleMath
def initialize
@result = 0
end
#1 add function
def add(val)
@result += val
self
end
#2 Subtract function
def subtract(val)
@result -= val
self
end
def to_s
@result
end
end
newNumber = SimpleMath.new
p newNumber.add(2).add(2).subtract(1)
Run Code Online (Sandbox Code Playgroud)
对于任何数量的论点
class SimpleMath
def initialize
@result = 0
end
#1 add function
def add(*val)
@result += val.inject(&:+)
self
end
#2 Subtract function
def subtract(*val)
@result -= val.inject(&:+)
self
end
def to_s
@result
end
end
newNumber = SimpleMath.new
p newNumber.add(1, 1).add(1, 1, 1, 1).subtract(1)
Run Code Online (Sandbox Code Playgroud)
让我们定义一个类的实例SimpleMath:
sm = SimpleMath.new #=> #<SimpleMath:0x000001020ca820>
Run Code Online (Sandbox Code Playgroud)
这里要注意三件事:
sm是一个变量.在Ruby中,变量由小写字母表示,可选地用下划线分隔(例如my_var).()后new,在new没有参数(又名"参数"),这是可选的,很少有人会这么做.return不存在,Ruby返回该方法执行的最后一次计算.在这里,您通常会简单地写下最后一行self,然后返回.唉,重要的是self,无论有或没有关键字return,返回都不是你想要的.在IRB中尝试以下内容:
sm.add(2) #=> #<SimpleMath:0x000001020ca820>
Run Code Online (Sandbox Code Playgroud)
毫无疑问,你会期待它返回2+0 #=> 2,但它会返回self,正如你在上面看到的那样,实际上是sm(#<SimpleMath:0x000001020ca820>).
您只需删除该行即可解决此问题:
return self
Run Code Online (Sandbox Code Playgroud)
来自add和subtract:
class SimpleMath
def add(a,b=0)
a + b
end
def subtract(a,b=0)
a - b
end
end
Run Code Online (Sandbox Code Playgroud)
现在
sm = SimpleMath.new
sm.add(2) #=> 2
Run Code Online (Sandbox Code Playgroud)
但是,如果我们试图链接另一个add,我们还有另一个问题:
sm.add(2).add(2,3) #=> NoMethodError: undefined method `add' for 2:Fixnum
Run Code Online (Sandbox Code Playgroud)
这个消息是很清楚的:类Fixnum,其中的2是一个实例,没有命名的实例方法add.那是因为你为班级定义了它SimpleMath,而不是为了Fixnum.
当Ruby执行时sm.add(2).add(3,4),它首先计算sm.add(2) #=> 2,这会将表达式减少到2.add(3,4).然后它尝试发送方法add(带有两个参数)2,但发现该类2.class #=> Fixnum没有实例方法add; 因此例外.
我们可以通过为类定义这些方法来纠正该错误Fixnum:
class Fixnum
def add(a,b=0)
a + b
end
def subtract(a,b=0)
a - b
end
end
Run Code Online (Sandbox Code Playgroud)
您可以Fixnum通过运行以下命令确认已将这些方法添加到类中:
Fixnum.instance_methods.sort
Run Code Online (Sandbox Code Playgroud)
现在,另一个问题:
sm = Fixnum.new #=> NoMethodError: undefined method `new' for Fixnum:Class
Run Code Online (Sandbox Code Playgroud)
哦,我的,班级Fixnum没new办法!那是因为实例Fixnum是整数,无法创建.您可以轻松确认整数是以下情况的实例Fixnum:
72.class #=> Fixnum
-3.class #=> Fixnum
Run Code Online (Sandbox Code Playgroud)
所以我们可以add通过将它发送到任何 Fixnum实例来调用该方法:
72.add(2) #=> 2
-3.add(2) #=> 2
Run Code Online (Sandbox Code Playgroud)
现在让我们尝试连锁add操作:
72.add(2).add(3,4) #=> 7
72.add(2000000).add(3,4) #=> 7
Run Code Online (Sandbox Code Playgroud)
没有例外,但没有链接.解决此问题的方法是再次更改方法:
class Fixnum
def add(b=0)
puts "in add, self = #{self}, b = #{b}"
self + b
end
def subtract(b=0)
puts "in subtract, self = #{self}, b = #{b}"
self - b
end
end
Run Code Online (Sandbox Code Playgroud)
我已经puts在每个方法中添加了一个语句,以防需要更多调试.当代码正常工作时,我们将删除它们.我们来测试一下:
2.add(3) #=> 5
in add, self = 2, b = 3
5.add #=> 5
in add, self = 5, b = 0
5.add(7) #=> 12
in add, self = 5, b = 7
2.add(3).add.add(7) #=> 12
in add, self = 2, b = 3
in add, self = 5, b = 0
in add, self = 5, b = 7
2.subtract(5) #=> -3
in subtract, self = 2, b = 5
-3.subtract #=> -3
in subtract, self = -3, b = 0
2.subtract(5).subtract #=> -3
in subtract, self = 2, b = 5
in subtract, self = -3, b = 0
2.add(3).subtract(5).add(7) #=> 7
in add, self = 2, b = 3
in subtract, self = 5, b = 5
in add, self = 0, b = 7
Run Code Online (Sandbox Code Playgroud)
成功!得到它?
| 归档时间: |
|
| 查看次数: |
7416 次 |
| 最近记录: |