gpt4 book ai didi

ruby - 我应该为实例变量使用什么约定?

转载 作者:数据小太阳 更新时间:2023-10-29 07:42:11 25 4
gpt4 key购买 nike

Ruby 代码中是否使用了任何实例变量约定?即,我注意到,在示例部分中,实例变量是使用“@”初始化的,然后代码使用不带“@”的变量名:

class BookInStock
attr_reader: isbn
attr_accessor: price

def initialize (isbn, price)
@isbn = isbn
@price = Float (price)
end

def price_in_cents
Integer (price * 100 + 0.5)
end
end

还有一些示例代码,实例变量一直使用前缀“@”

class BookStock

def set_price (price)
@price = price
end

def get_price
@price
end
end

这些记录有什么区别?什么时候应该只在对象的初始化中使用“@”,什么时候在所有类方法中使用?

最佳答案

如果您为该变量定义了属性读取器(使用attr_readerattr_accessor),则只能使用不带@ 的实例变量名称.这是一个轻量级助手,用于创建返回实例变量值的方法。

区别在于使用类的公共(public)接口(interface)还是访问私有(private)数据之间的问题。例如,建议在子类或包含的模块中使用公共(public)接口(interface)。这确保了封装。因此,您不应从子类或模块中访问实例变量。

在类本身中,问自己这个问题:如果属性的实现发生变化,我对属性的使用是否也应该改变?如果答案是,则直接使用实例变量;如果是,则使用公共(public)属性。

一个例子。假设我们有一个 Person 类代表一个人并且应该包含那个人的名字。首先是这个版本,只有一个简单的 name 属性:

class Person
attr_reader :name

def initialize(name)
@name = name
end

def blank?
!@name
end

def to_s
name
end
end

请注意我们如何为 blank? 方法使用实例变量,而为 to_s 使用public 属性> 方法。这是故意的!

假设在重构步骤中,我们决定 Person 类应该分别跟踪 first_namelast_name

class Person
def initialize(first_name, last_name)
@first_name, @last_name = first_name, last_name
end

def name
"#{@first_name} #{@last_name}"
end

def blank?
!@first_name and !@last_name
end

def to_s
name
end
end

我们现在将 name 属性更改为常规方法,该方法根据一个人的名字和姓氏组成名字。我们现在可以看到可以为 to_s 保留相同的实现。但是,blank? 需要更改,因为它依赖于基础数据。这就是to_s使用属性,而blank?使用实例变量的原因。

当然,区分并不总是那么容易。如有疑问,请选择公共(public) API 而不是访问私有(private)数据。

关于ruby - 我应该为实例变量使用什么约定?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7555106/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com