ruby - 在 Ruby 中修改匿名数组中的模块级变量

标签 ruby map

我正在学习 Ruby,并认为我对以下代码很聪明:

[@start,@end].map!{ |time| time += operation == :add ? amount : -(amount) }

其中@start、@end 是两个模块级变量,operation 可以是:add 或:sub 之一,amount 是一个 float ,用于调整@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)}

您会注意到我们也没有在处理 :add:sub 业务——我们可以只传递我们想要的消息的实际名称发送(我在这种情况下使用 +,但它可以是任何东西)。

如果您有一个很大的、动态生成的要设置的 ivar 列表,它只会稍微复杂一点。唯一的区别是需要按名称获取和设置 ivar。

ivars = [:@start, :@end, :@something_else]
operation = :+
amount = 12
ivars.each {|ivar| instance_variable_set(ivar, instance_variable_get(ivar).send(operation, amount))}

关于ruby - 在 Ruby 中修改匿名数组中的模块级变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1490816/

相关文章:

ruby - Ruby 异常实例在哪里保存它们的消息?

python - 如何使用 Python 打包一个大整数,将四个字符视为网络字节顺序中的无符号长整型,就像 Ruby 的 .pack ("N"那样?

java - JAXB 编码列表映射

java - 使用动态类引用时抑制警告

java - Java从Map中获取值的范围

ruby-on-rails - 使用 Spork、Guard、RSpec 的 Rails 引擎测试/虚拟机?

ruby - 有没有更好的方法来查找数组中最小元素的位置?

ruby-on-rails - 不允许的参数 : :utf8, :authenticity_token - Rails 5. 2 form_with

map - 为什么我的unordered_map自己订购?

c++ - 为什么 insert from std::map 不想更新? [C++]