【问题标题】:Im trying to understand "Getters" and "Setters" in the ruby programming language我试图理解 ruby​​ 编程语言中的“Getters”和“Setters”
【发布时间】:2023-03-06 01:24:01
【问题描述】:

我目前正在做一些关于 ruby​​ 编程语言的在线教程,我认为到目前为止我得到的解释/示例是缺乏的。在直接提问之前,我有两个例子想给你看。

第一个例子是:

传统的 Getter/Setter;

class Pen

  def initialize(ink_color)
    @ink_color = ink_color # this is available because of '@'
  end

  # setter method
  def ink_color=(ink_color)
    @ink_color = ink_color
  end

  # getter method
   def ink_color
    @ink_color
  end

end

第二个例子是:

ShortCutt Getter/Setter;

class Lamp
  attr_accessor :color, :is_on

  def initialize(color, is_on)
    @color, @is_on = color, false
  end
end

好的,所以对于第一个示例,我认为它非常简单。我正在整个 Lamp 类中“初始化”一个可访问的变量,名为“@ink_color”。如果我想将“@ink_color”设置为红色或蓝色,我只需调用我的“Setter”方法并将“red”或“blue”传递给我的 setter 中的参数 (ink_color)。然后,如果我想访问或“获取/获取”我拥有“设置/设置”的颜色,我会调用我的获取方法并询问“墨水颜色”。

第二个例子对我来说也很有意义; ruby 提供了一个“快捷方式”,基本上可以运行代码来为您构建 getter 和 setter,而不是输入 getter 和 setter 方法的样子。

但问题来了 - 我如何对“快捷方式”版本进行逆向工程?假设我正在查看上面的快捷方式示例,并想以没有快捷方式的“传统”方式进行操作?

“快捷方式”的逆向工程是否类似于下面的代码(我的尝试对我来说似乎不正确)......

我的尝试/示例

class Lamp

  def initialize(color, is_on)
    @color = color
    @is_on = is_on
  end

  def color=(color)
    @color = color
  end

   def is_on=(is_on)
    @is_on = is_on
  end

  def color
    @color
  end

  def is_on
    @is_on
  end

end

我的尝试是正确/可行的代码吗?当涉及到这个 getter/setter 东西时,我似乎在概念上错过了一部分。

【问题讨论】:

  • 是的,这正是attr_accessor 所做的。
  • “我的尝试对我来说似乎不合适” - 为什么你觉得它不合适?
  • 也许我对这门语言很陌生。我想我应该说:“我的尝试”的行为/执行方式是否与快捷方式完全相同?
  • @Ghoyos 是的。

标签: ruby setter getter


【解决方案1】:

了解 attr_accesor、attr_reader 和 attr_writer

这些是 Ruby 的 getter 和 setter 快捷方式。它像 C# 属性一样工作,注入 get_Prop (getter) 和 set_Prop (setter) 方法。

  • attr_accessor:注入prop(getter)和prop=(setter)方法。
  • attr_reader:这是只读属性的快捷方式。注入prop 方法。 prop 的值只能在类内部更改,操作实例变量@prop
  • attr_writer:这是只写属性的快捷方式。注入prop= 方法。

Ruby 没有称为get_prop(getter)和set_prop(setter)的方法,而是称为prop(getter)和prop=(setter)。

话虽如此,你可以推断

class Person
  attr_accessor :name, :age
end

的简短版本
class Person
  # getter
  def name
    return @name
  end

  # setter
  def name=(value)
    @name = value
  end
end

您无需调用return,Ruby 方法返回最后执行的语句。

如果您使用的是 Ruby on Rails gem,您可以使用 new 构建模型对象并将属性值作为参数传递,就像:

p = Person.new(name: 'Vinicius', age: 18)
p.name
=> 'Vinicius'

这是可能的,因为 Rails 向 ActiveRecord::Base 和包含 ActiveModel::Model 的类注入了类似 initialize 的方法:

def initialize(params)
  params.each do |key, value|
    instance_variable_set("@#{key}", value)
  end
end

【讨论】:

  • 如果您使用的是 Ruby on Rails gem,您可以使用新的和传递的属性构建任何对象 - 我认为这不是真的。一个类必须扩展 ActiveRecord::Base 或包含 ActiveModel::Model 才能获得该行为。
  • 这里的return 已经是隐含的,并没有真正增加清晰度,反而会引起不必要的注意。
  • 值得注意的是,实际的 ActiveRecord 实现本身并没有使用像这样的属性,而是一个更复杂的系统,可以跟踪属性的变化,并可以通过方法和原始数据库区分数据表达式值。
猜你喜欢
  • 1970-01-01
  • 2015-11-04
  • 1970-01-01
  • 2019-01-21
  • 2015-06-04
  • 2017-12-21
  • 1970-01-01
  • 1970-01-01
  • 2015-10-15
相关资源
最近更新 更多