我正在學習紅寶石,我的看法attr_reader很糟糕。因為您可以從類外部更改特定實體變數的值。例如:
class X
attr_reader :some_string
def initialize
@some_string = "abc"
end
end
tmp = X.new
puts tmp.some_string
tmp.some_string[0] = "aaaaaaaaa"
puts tmp.some_string
當您運行此代碼時,您可以看到實體變數some_string已更改。所以為了避免這種情況,我總是制作自己的吸氣劑,并回傳frozen物件。例如:
class X
def initialize
@some_string = "abc"
end
def some_string
@some_string.freeze
end
end
tmp = X.new
puts tmp.some_string
tmp.some_string[0] = "aaaaaaaaa"
puts tmp.some_string
現在,當您運行代碼時,它會拋出一個錯誤can't modify frozen String: "abc",這就是我想要的。所以我的問題是我應該使用attr_reader并且總是frozen從吸氣劑不良做法中回傳物件嗎?
uj5u.com熱心網友回復:
attr_reader并不“壞”,它只是做了它所做的事情,即回傳實體變數的值,它是一個參考。不同attr_writer,否則attr_accessor它不允許您更改實體變數的值(即您不能更改實體變數所指的內容)
問題是你真的想要還是需要參考。例如,假設您要將 some_string 的值轉換為大寫。您可以使用attr_reader來獲取參考some_string,然后呼叫大寫!像下面這樣。但是擁有參考允許您呼叫物件上的任何方法,包括您可能不想允許的 []= 方法。注意: []= 是一種操作 some_string 參考的內容的方法,它沒有將 @some_string 設定為新值,它仍然指向同一個物件,但它指向的物件被操作了。
class Foo
attr_reader :some_string
def initialize()
@some_string = "abc"
end
end
puts "Foo"
foo = Foo.new
some_string = foo.some_string
puts some_string #=> abc
some_string.upcase!
p foo # => #<Foo:0x0000563c38391ac8 @some_string="ABC">
puts some_string.object_id # => 60
some_string[0] = "x"
p foo # => #<Foo:0x0000563c38391ac8 @some_string="xBC">
puts some_string.object_id # => 60 ... ie same object different content
# foo.some_string = "ABC" is a runtime error
如果您不想允許在實體變數上呼叫任意方法,則不應使用 公開它attr_reader,而應通過類中的方法操作實體變數。例如下面我“委托”大寫!方法到實體變數@some_string,我提供了一個string_value方法來回傳一個與實體變數具有相同值的新字串。
class Bar
def initialize()
@some_string = "abc"
end
def upcase!()
@some_string.upcase!
end
def string_value()
"#{@some_string}"
end
end
puts "Bar"
bar = Bar.new
p bar # => #<Bar:0x0000563c383915a0 @some_string="abc">
bar.upcase!
p bar # => #<Bar:0x0000563c383915a0 @some_string="ABC">
some_string = bar.string_value
p some_string # => "ABC"
some_string[0] = "x"
p bar # => #<Bar:0x0000563c383915a0 @some_string="ABC">
p some_string # => "xBC"
所以我想說attr_reader還不錯,你可能會說它被過度使用了,我知道我經常用它來“獲取”一個實體變數,而我真正需要的只是實體變數上的一些屬性。
uj5u.com熱心網友回復:
許多開發人員嘗試使用私有attr_reader并在類中使用它或完全避免使用它關于attr_reader的良好對話在這里和這里
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/489066.html
