【发布时间】:2010-11-14 17:46:31
【问题描述】:
你能举个例子吗?
【问题讨论】:
标签: ruby attributes methods
你能举个例子吗?
【问题讨论】:
标签: ruby attributes methods
属性只是一个捷径。如果您使用attr_accessor 创建属性,Ruby 只需声明一个实例变量并为您创建getter 和setter 方法。
既然你问了一个例子:
class Thing
attr_accessor :my_property
attr_reader :my_readable_property
attr_writer :my_writable_property
def do_stuff
# does stuff
end
end
这是你如何使用这个类:
# Instantiate
thing = Thing.new
# Call the method do_stuff
thing.do_stuff
# You can read or write my_property
thing.my_property = "Whatever"
puts thing.my_property
# We only have a readable accessor for my_readable_property
puts thing.my_readable_property
# And my_writable_propety has only the writable accessor
thing.my_writable_property = "Whatever"
【讨论】:
属性是对象的特定属性。方法是对象的能力。
在 Ruby 中,所有实例变量(属性)默认都是私有的。这意味着您无法在实例本身范围之外访问它们。 访问属性的唯一方法是使用访问器方法。
class Foo
def initialize(color)
@color = color
end
end
class Bar
def initialize(color)
@color = color
end
def color
@color
end
end
class Baz
def initialize(color)
@color = color
end
def color
@color
end
def color=(value)
@color = value
end
end
f = Foo.new("red")
f.color # NoMethodError: undefined method ‘color’
b = Bar.new("red")
b.color # => "red"
b.color = "yellow" # NoMethodError: undefined method `color='
z = Baz.new("red")
z.color # => "red"
z.color = "yellow"
z.color # => "yellow"
因为这是一种非常常见的行为,Ruby 提供了一些方便的方法来定义访问器方法:attr_accessor、attr_writer 和 attr_reader。
【讨论】:
属性,严格来说,是类实例的实例变量。更一般地说,属性通常使用 attr_X 类型的方法声明,而方法则按原样声明。
一个简单的例子可能是:
attr_accessor :name
attr_reader :access_level
# Method
def truncate_name!
@name = truncated_name
end
# Accessor-like method
def truncated_name
@name and @name[0,14]
end
# Mutator-like method
def access_level=(value)
@access_level = value && value.to_sym
end
这两者之间的区别在 Ruby 中有些随意,因为没有专门提供对它们的直接访问。这与其他语言(如 C、C++ 和 Java)形成鲜明对比,其中对象属性的访问和调用方法是通过两种不同的机制完成的。尤其是 Java 具有这样拼写出来的访问器/修改器方法,而在 Ruby 中,这些是通过名称来暗示的。
通常情况下,如示例中所示,“属性访问器”和根据属性值提供数据的实用程序方法(例如 truncated_name)之间的差异很小。
【讨论】:
class MyClass
attr_accessor :point
def circle
return @circle
end
def circle=(c)
@circle = c
end
end
属性是对象的属性。在这种情况下,我使用 attr_accessor 类方法来定义 :point 属性以及 point 的隐式 getter 和 setter 方法。
obj = MyClass.new
obj.point = 3
puts obj.point
> 3
方法“circle”是@circle 实例变量显式定义的getter。 'circle=' 是为 @circle 实例变量显式定义的设置器。
【讨论】:
我听说“属性”这个词在 Ruby 特定的圈子中指的是任何不带参数的方法。
class Batman
def favorite_ice_cream
[
'neopolitan',
'chunky monkey',
'chocolate',
'chocolate chip cookie dough',
'whiskey'
].shuffle[0]
end
end
在上面,my_newest_batman.favorite_ice_cream 将是一个属性。
【讨论】: