Ruby - Structs和命名参数继承

ker*_*lin 14 ruby inheritance struct

这个问题严格来说是关于结构行为的,所以请不要"为什么在广泛的体育世界中你这样做呢?"

这段代码是INCORRECT,但它应该说明我想要了解的Ruby Structs:

class Person < Struct.new(:name, :last_name)
end

class ReligiousPerson < Person(:religion)
end

class PoliticalPerson < Person(:political_affiliation)
end

### Main ###

person = Person.new('jackie', 'jack')
pious_person = ReligiousPerson.new('billy', 'bill', 'Zoroastrianism')
political_person = PoliticalPerson.new('frankie', 'frank', 'Connecticut for Lieberman')
Run Code Online (Sandbox Code Playgroud)

如您所见,尝试使用Structs定义类继承.但是,当你尝试初始化ReligiousPerson或PoliticalPerson时,Ruby会变得暴躁.因此,给定这个说明性代码,如何使用Structs使用这种类继承继承命名参数?

knu*_*nut 16

您可以在Person中定义新的Structs:

class Person < Struct.new(:name, :last_name)
end

class ReligiousPerson < Struct.new(*Person.members, :religion)  
end

class PoliticalPerson < Struct.new(*Person.members, :political_affiliation)
end

### Main ###

person = Person.new('jackie', 'jack')
p pious_person = ReligiousPerson.new('billy', 'bill', 'Zoroastrianism')
p political_person = PoliticalPerson.new('frankie', 'frank', 'Connecticut for Lieberman')
Run Code Online (Sandbox Code Playgroud)

结果:

#<struct ReligiousPerson name="billy", last_name="bill", religion="Zoroastrianism">
#<struct PoliticalPerson name="frankie", last_name="frank", political_affiliation="Connecticut for Lieberman">
Run Code Online (Sandbox Code Playgroud)

在发布我的回答后我马上就有了一个想法:

class Person < Struct.new(:name, :last_name)
  def self.derived_struct( *args )
    Struct.new(*self.members, *args)
  end
end

class ReligiousPerson < Person.derived_struct(:religion)  
end

class PoliticalPerson < Person.derived_struct(:political_affiliation)
end

### Main ###

person = Person.new('jackie', 'jack')
p pious_person = ReligiousPerson.new('billy', 'bill', 'Zoroastrianism')
p political_person = PoliticalPerson.new('frankie', 'frank', 'Connecticut for Lieberman')
Run Code Online (Sandbox Code Playgroud)

工作良好!

您还可以将#derived_struct添加到Struct:

class Struct
  def self.derived_struct( *args )
    Struct.new(*self.members, *args)
  end
end
Run Code Online (Sandbox Code Playgroud)