有和没有成员的结构

时间:2016-10-16 09:45:37

标签: ruby struct

我是一个新的Rubyist,目前我将在类中使用Struct来创建一个临时对象。但是,当我在Struct中使用这样的成员时遇到一个问题:

class A
  attr_accessor :b
  B = Struct.new(:name, :print_name) do
    def print_name
      p "Hello #{name}"
    end
  end

  def initialize(input_name)
    @b = B.new(input_name)
  end
end

a = A.new('Leo')
a.b.print_name # Hello Leo

但是当我的Struct B参数不包括:print_name时,我也会得到相同的结果。

B = Struct.new(:name) do
...
end

那有什么不同?什么时候我应该使用成员参数,当我不是?

由于

1 个答案:

答案 0 :(得分:3)

在第一种情况下,您定义了一个类,其初始化程序采用两个参数 - nameprint_name

在第二种情况下,您定义了一个类,其初始化程序采用单个参数 - name

这与您正在定义名为print_name的实例方法这一事实无关。

因此,两个类的实例(有和没有print_name参数)都定义了print_name方法,因此两个示例的工作方式相同。

检查创建的对象时,可以看到差异:

# first case with two arguments
foo = B.new(:a, :b)
foo.inspect
=> "#<struct B name=:a, print_name=:b>"

# second case with single argument
foo = B.new(:a)
foo.inspect
=> "#<struct B name=:a>"

此外,当您在两种情况下检查B类的实例方法时,您可以看到差异:

# first case with two arguments
B.instance_methods false
#=> [:name, :name=, :print_name, :print_name=]

# second case with single argument
B.instance_methods false
#=> [:name, :name=, :print_name]
  

但是当我的结构B参与者不同时,我也会得到相同的结果   包括:print_name

不同之处在于,在第一种情况下,您可以执行以下操作:

a.b.print_name = 'new print name'
a.b.inspect
#=> "#<struct B name='Leo', print_name='new print name'>"

而在第二种情况下,它将失败:

a.b.print_name = 'new print name'
#=> NoMethodError: undefined method 'print_name=' for #<struct B name='Leo'>