Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Ruby类中定义类方法和属性的正确方法_Ruby - Fatal编程技术网

在Ruby类中定义类方法和属性的正确方法

在Ruby类中定义类方法和属性的正确方法,ruby,Ruby,我正在尝试用Ruby编写一个Person类,它有一些方法和属性。下面是我现在是如何实现它的 class Person attr_accessor :name, :gender, :mother def initialize(name, gender, mother) @name = name @gender = gender @mother = mother @spouse = nil end def add_spouse(spouse)

我正在尝试用Ruby编写一个
Person
类,它有一些方法和属性。下面是我现在是如何实现它的

class Person
  attr_accessor :name, :gender, :mother

  def initialize(name, gender, mother)
    @name = name
    @gender = gender
    @mother = mother
    @spouse = nil
  end

  def add_spouse(spouse)
    if spouse
      @spouse = spouse
      spouse.spouse = self
    end
  end
  
  def father(self)
    return [self.mother.spouse]
  end
end
我想访问如下方法:

m = Person.new('mom', 'Female')
d = Person.new('dad', 'Male')

d.add_spouse(m)

p = Person.new('Jack', 'Male', m)

如果我想得到
p
父亲
,那么我想得到这样的父亲:
p.father

那么,上述实现是否正确

如果我运行代码,我将收到以下错误:

person.rb:18: syntax error, unexpected `self', expecting ')'
  def father(self)
person.rb:21: syntax error, unexpected `end', expecting end-of-input
如果我从
def-father(self)
中删除
self
,则我会收到以下错误:

person.rb:14:in `add_spouse': undefined method `spouse=' for #<Person:0x00005570928382d8> (NoMethodError)
person.rb:14:in'add_party':为#(NoMethodError)未定义的方法'party='
我的错误在这里:
attr\u访问者:配偶
。我必须添加这个,要访问它,我必须执行
put(p.father[0].name)

有没有更好的方法可以用类似的其他属性来实现上述类,如
父类
子类
兄弟类
等?

看看-

class Person
  attr_accessor :name, :gender, :mother, :spouse

  def initialize(name, gender, mother)
    @name = name
    @gender = gender
    @mother = mother
    @spouse = nil
  end

  def add_spouse(spouse)
    if spouse
      @spouse = spouse
      @spouse.spouse = self
    end
  end
  
  def father()
    return [self.mother.spouse]
  end
end
输出-

m = Person.new('mom', 'Female', nil)
d = Person.new('dad', 'Male', nil)
d.add_spouse(m)
p = Person.new('Jack', 'Male', m)

正如在一篇评论中所写,这更像是Ruby中的一个问题,所有东西都是一个对象,几乎所有东西都不包括块等。Ruby使用
类作为
对象的定义,它们建立
属性
方法

您的代码为
姓名
性别
母亲
设置属性,并具有添加配偶
和父亲
的方法。因此,父亲被解释为属性和方法是一个明显的混合体。从命名约定的角度来看,我们可以重命名该方法
collect\u father\u relation
或类似的东西,它将处理逻辑以呈现对象

您也不需要像在
father
方法中那样显式地编写
return
,Ruby会为您这样做

我会将
father
方法重新配置为以下内容:

def collect_father_relation
  @mother&.spouse
end
调用
@mother
instance_变量,定义实例,并且仅在
@mother
存在时(可以是
nil
)调用
&.
运算符

您还应该为传递的
nil
母亲准备
initialize
函数:

def initialize(name, gender, mother = nil)
这将接受一个母参数,但如果没有传递,也不会引发
ArgumentError

最后,您必须为
:party
添加一个
attr\u访问器,因为在
party.party=self
中设置关系时,您需要为party-Person对象显式引用
party

其他意见:

让我们为
add\u party
方法(如上所述)创建一个保护子句,以明确解释我们正在做什么,而不是含糊不清的if语句

  def add_spouse(spouse)
    return if spouse.nil?
    
    @spouse = spouse
    spouse.spouse = self
  end

当你尝试它时发生了什么?我在问题中添加了错误。这实际上更像是一个问题,你所说的“更好的方式”是什么意思?“更好”是主观的,但只允许客观的问题。为了使问题客观化,你需要对“改善”给出一个精确、明确、客观的可测量的定义。如果你能稍微解释一下你的代码也会有帮助。为什么父方法返回数组?你希望一个人有多少个父亲?一个人的父亲是母亲的现任配偶,也就是说,如果母亲再婚,父亲就会改变,如果母亲去世,父亲也会死去,这是真的吗?@JörgWMittag更好的说法是,我的意思是,是否使用
self.some_variable
@some_variable
,因为我看到了这两个例子。对于
父亲
而言,它始终是
母亲
的当前配偶。这就是我最初想要的。另外,我所说的更好,是指在python中,我们使用
@property
将方法作为属性。那么在ruby中我应该使用类似的东西吗?