我是一个Ruby新手,我正在尝试定义一个包含3个实例变量的类,即unit_rows,unit_cols和unit_sz。在这个类中,我希望unit_rows和unit_cols可以从外部自由获取和设置,但我希望unit_sz被计算(即不可设置)为(unit_rows * unit_cols)。我希望unit_sz实例变量可以从另一个类获取,但该值应该是返回之前行和列的乘积。这个类将扩展许多变量,如“unit_sz”,因此我想动态迭代所有实例变量
案例:
我如何确保“unit_sz”实例变量作为产品正确计算,当我从外部调用并动态迭代类“returnVars”方法中的实例变量时?
另外,我如何声明一个本地类变量,可以同时使用我的meth1和meth2(不传递值)但不能从外部访问?我可以通过定义没有getter / setter的类实例变量来实现它 - 这是正确的方法
提前感谢!
以下是我的代码
#!/usr/local/bin/ruby -w
class Unit
def initialize
@unit_cols = 2
@unit_rows = 2
@unit_sz = 6
end
attr_accessor :unit_cols, :unit_rows
#attr_reader :unit_sz
def unit_sz
@unit_sz = @unit_rows * @unit_cols
end
def returnVars
ret_str = ""
temp = self.instance_variables
for param in temp
key = param.to_s
val = instance_variable_get(("" + key).intern)
key = key[1..-1]
ret_str << "#{key.upcase} = #{val.to_s};" << "\n"
end
puts "check1 = #{self.unit_sz}"
return ret_str
end
#meth1
def meth1
end
#meth2
def meth2
end
end
unit = Unit.new
#puts "unit_sz = #{unit.unit_sz}"
puts "#{unit.returnVars}"
答案 0 :(得分:0)
没有理由(我可以从你的问题中看到)@unit_sz
需要是一个实例变量 - 你可以将它视为一种方法。有些情况下你可能想要设置一个ivar(缓存,memoization等),但对于这个简单的情况,unit_sz
应该是:
def unit_sz
unit_rows * unit_cols
end
请注意,此方法使用访问器而不是直接访问实例变量。一般来说,这是一种很好的做法,因为值是消息发送的结果,您可以在增长或扩展类时利用它。实例变量应该在initialize
或其各自的设置器中设置,但通常不在其他地方。
在迭代所有实例变量时,您实际上是在创建一个自定义inspect
方法,但您事先不知道自己定义了哪些实例变量。这里的麻烦在于你有行为和数据的融合。类的结构(它的实例变量和方法)应该定义行为,变量应该保存数据,但是在这里,因为你有可变数量的变量,所以任何特定实例的结构都倾向于数据方面。如果需要任意数量的键值对,请使用哈希。但是,我认为你没有这样做,因为已经解决了@unit_sz
问题。
至于你的上一个问题,你似乎是在定义一个静态变量(即没有getter或setter,所以只有你在类中定义的值)。您可以使用常量(MY_VAR = 5
)或私有方法(我更喜欢):
class Unit
private
def my_var
5
end
end