我正在学习Ruby,并认为我对以下代码很聪明:
[@start,@end].map!{ |time| time += operation == :add ? amount : -(amount) }
Run Code Online (Sandbox Code Playgroud)
其中@start,@ end是两个模块级变量,操作可以是:add或:sub,而amount是一个浮点数,用于调整@start和@end.
当然,它只为我节省了一行代码,但为什么这种方法不起作用,我怎么能得到类似的东西呢?
(我的预期输出是相应地修改@ start/@ end,但是单元测试显示它们保持原始值.)
在Ruby中重要的是要记住变量和它们所拥有的对象之间的区别.简单地设置变量永远不会改变该变量引用的对象.当你这样做时a += b
,它只是简写a = a + b
.因此,您要为变量a分配一个新值,而不是更改曾经存在的对象或更改对该对象的任何其他引用.所以改变变量time
不会改变@start
.
为了分配实例变量,您需要实际分配给该实例变量.这是一种做你想要的方法:
operation = :+
amount = 12
@start, @end = [@start, @end].map {|time| time.send(operation, amount)}
Run Code Online (Sandbox Code Playgroud)
你会注意到我们也没有对这个:add
和:sub
业务感到不满- 我们可以只传递我们想要发送的消息的实际名称(我在这种情况下使用+,但它可以是任何东西).
如果你想要设置一个动态生成的大型ivars列表,那么它只会有点复杂.唯一的区别是需要按名称获取和设置ivars.
ivars = [:@start, :@end, :@something_else]
operation = :+
amount = 12
ivars.each {|ivar| instance_variable_set(ivar, instance_variable_get(ivar).send(operation, amount))}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
720 次 |
最近记录: |