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
ruby方法是否应该修改类';s实例方法?_Ruby_Oop - Fatal编程技术网

ruby方法是否应该修改类';s实例方法?

ruby方法是否应该修改类';s实例方法?,ruby,oop,Ruby,Oop,我正在用Ruby编写一个类,其中有类的实例变量(即@person\u summary\u info,@name,@dob,@favorite\u food) 要解析一段文本,我有一个从类外部调用的公共方法(我们称之为explorate) 此方法调用一些私有类方法,如get\u name,这些方法使用@person\u summary\u info提取相应的信息(在本例中,是人名)。这些私人方法应: a) 使用实例@person\u summary\u info,或通过传递给它们的参数获取该信息(

我正在用Ruby编写一个类,其中有类的实例变量(即
@person\u summary\u info
@name
@dob
@favorite\u food

要解析一段文本,我有一个从类外部调用的公共方法(我们称之为
explorate

此方法调用一些私有类方法,如
get\u name
,这些方法使用
@person\u summary\u info
提取相应的信息(在本例中,是人名)。这些私人方法应:

a) 使用实例@person\u summary\u info,或通过传递给它们的参数获取该信息(即
get\u name
vs
get\u name(person\u summary\u info)

b) 直接修改实例变量并不返回任何内容,或者在函数范围外不修改任何内容并返回结果(即在
get_name
、set
@name='John'
、或
返回'John'

这里的最佳实践是什么? 谢谢

> p>如果解释()不意味着改变一个特定实例的状态,那么考虑将方法命名为GETJNAMEYOFFEXString(String),并且可能使其静态化,因为它对实例的状态没有任何作用。

如果你想通过解释()来改变一个人的特定实例的状态,那么考虑改变方法的名称,用SET预先设置它,并包括所设置的属性名称(StIGNAMENEFROM STRIGN())。如果正在设置多个属性,那么可能会从_string()中设置_,并包含一条代码注释,说明正在修改哪些实例变量。在内部,该方法可以调用get/set_name(),如下所述

通常,getter/setter方法是公共的,应该非常简单,按照其名称执行: -getName()返回实例变量@name -setName(name)使用传入的值设置或覆盖实例变量@name,但不返回任何内容


在Java中,这是一种类型,特别是Java bean(不包括关于需要可序列化的部分),它在几种不同语言中非常常见的编程实践是为实例变量使用公共setter/getter方法,并且还具有默认构造函数(不带参数的构造函数)另一个构造函数允许您在实例化对象时设置实例变量。

直接从另一个类使用@instance是一个解决问题的好方法。每个类都应该有自己的变量,并且您想要处理或返回的任何内容都应该直接分配/返回。。也就是说

@instance = my_class.get_name(person_summary_info)
而不是

my_class.get_name
试想一下如何使用@instance变量测试代码,并有机会重用这段代码


就我的2c

我已经在我的答案底部的代码中包含了我对您问题的最佳表述,但我想先介绍我的解决方案,因为我了解您的困境

如果您的
名称
属性要公开访问,请执行此操作:

class Person
  attr_accessor :name

  def initialize(name)
    @name = name
  end

  def interpret(text_to_parse)
    # I have no idea what you are parsing in real life
    self.name = text_to_parse.split.last
  end
end

person = Person.new("Frederick")
puts person.name
# => "Frederick"
person.interpret("Please, call me Fred")
puts person.name
# => "Fred"

如果您的
name
属性不应该(容易)公开访问,请执行此操作:(值得一提的是,在Ruby中,几乎任何东西都可以通过这种或那种方式访问。这是许多让它很棒的东西之一!)


如上所述,以下是我将您的问题翻译成代码的最佳译文:

class Person
  def initialize
    @person_summary_info = { name: "foo" }
    @name = "bar"
    @dob = "baz"
    @favorite_food = "beer"
  end

  def interpret(text_to_parse)
    # Some kind of parsing?
    get_name_1
    # OR
    get_name_2(@person_summary_info)
    # OR
    get_name_3
    # OR
    @name = get_name_4
  end

  private
  def get_name_1
    @person_summary_info[:name]
  end

  def get_name_2(person_summary_info)
    person_summary_info[:name]
  end

  def get_name_3
    @name = 'John'
  end

  def get_name_4
    'John'
  end
end
希望你能明白为什么在评论中会对你的提问产生一些困惑。如果没有其他问题,也许看到这一点会帮助你更清楚地形成你的问题,以便我们能够提供帮助


最后,,你应该避免用Ruby编写你自己的getter/setter,除非你需要在获取/设置过程中加入一些自定义代码——使用类级的
attr\u reader
/
attr\u writer
/
attr\u accessor
宏为你创建它们。

你能把它作为示例代码重新编写吗?如果你打算提供奖励的话在这个问题上,你不妨试着让你的问题更容易理解。您可以将其作为示例代码重新编写吗?explorate()方法是否意味着是一个setter,即它解析传入的字符串,并相应地设置类的信息?
class Person
  def initialize
    @person_summary_info = { name: "foo" }
    @name = "bar"
    @dob = "baz"
    @favorite_food = "beer"
  end

  def interpret(text_to_parse)
    # Some kind of parsing?
    get_name_1
    # OR
    get_name_2(@person_summary_info)
    # OR
    get_name_3
    # OR
    @name = get_name_4
  end

  private
  def get_name_1
    @person_summary_info[:name]
  end

  def get_name_2(person_summary_info)
    person_summary_info[:name]
  end

  def get_name_3
    @name = 'John'
  end

  def get_name_4
    'John'
  end
end