Ruby - 类实例变量getter setter方法

时间:2014-02-11 20:39:00

标签: ruby variables instance setter getter

我是一个Ruby新手,我正在尝试定义一个包含3个实例变量的类,即unit_rows,unit_cols和unit_sz。在这个类中,我希望unit_rows和unit_cols可以从外部自由获取和设置,但我希望unit_sz被计算(即不可设置)为(unit_rows * unit_cols)。我希望unit_sz实例变量可以从另一个类获取,但该值应该是返回之前行和列的乘积。这个类将扩展许多变量,如“unit_sz”,因此我想动态迭代所有实例变量

案例:

  1. 当我实例化类并打印unit_inst.unit_sz时,它会正确地将值打印为产品
  2. 当我不调用“unit_sz”的getter方法时,当我调用方法returnVars,动态迭代实例变量并打印值时,我得到INCORRECT回答“6”,这是构造函数中的默认值
  3. 当我调用“unit_sz”的getter方法时,当我调用方法returnVars,它动态迭代实例变量并打印值时,我得到了CORRECT产品
  4. 明确调用“self.unit_sz”会正确打印该值,但无法动态执行此操作
  5. 我如何确保“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}"
    

1 个答案:

答案 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