irb(main):001* class User
irb(main):002* attr_reader :name
irb(main):003*
irb(main):004* def initialize(name, weight)
irb(main):005* @name = name
irb(main):006* @weight = weight
irb(main):007* end
irb(main):008*
irb(main):009* def heavier_than?(other_user)
irb(main):010* other_user.weight < @weight
irb(main):011* end
irb(main):012> end
=> :heavier_than?
irb(main):013> alice = User.new("Alice", 50)
=> #<User:0x0000000106eeb658 @name="Alice", @weight=50>
irb(main):014> bob = User.new("BoB",60)
=> #<User:0x0000000106f1bc90 @name="BoB", @weight=60>
irb(main):015> alice.heavier_than?(bob)
(irb):10:in `heavier_than?': undefined method `weight' for #<User:0x0000000106f1bc90 @name="BoB", @weight=60> (NoMethodError)
other_user.weight < @weight
^^^^^^^
...
irb(main):001* class User
irb(main):002* attr_reader :name, :weight
irb(main):003*
irb(main):004* def initialize(name, weight)
irb(main):005* @name = name
irb(main):006* @weight = weight
irb(main):007* end
irb(main):008*
irb(main):009* def heavier_than?(other_user)
irb(main):010* other_user.weight < @weight
irb(main):011* end
irb(main):012> end
=> :heavier_than?
irb(main):013> alice = User.new("Alice", 50)
=> #<User:0x00000001085f3e18 @name="Alice", @weight=50>
irb(main):014> bob = User.new("BoB", 60)
=> #<User:0x0000000108572930 @name="BoB", @weight=60>
irb(main):015> alice.heavier_than?(bob)
=> false
- アクセサメソッドで
weight
は読み込みできないようになっている
protectedメソッド
外部には公開したくないが、同じクラスやサブクラスの中であればレシーバ付きで呼び出せるようにしたい
、という時に登場するのがprotectedメソッドです。
protectedメソッドを試してみる
irb(main):001* class User
irb(main):002* attr_reader :name
irb(main):003*
irb(main):004* def initialize(name, weight)
irb(main):005* @name = name
irb(main):006* @weight = weight
irb(main):007* end
irb(main):008*
irb(main):009* def heavier_than?(other_user)
irb(main):010* other_user.weight < @weight
irb(main):011* end
irb(main):012*
irb(main):013* protected
irb(main):014*
irb(main):015* def weight
irb(main):016* @weight
irb(main):017* end
irb(main):018> end
=> :weight
irb(main):019> alice = User.new("Alice",50)
=> #<User:0x0000000103de9168 @name="Alice", @weight=50>
irb(main):020> bob = User.new("Bob", 60)
=> #<User:0x00000001003c3178 @name="Bob", @weight=60>
irb(main):021> alice.heavier_than?(bob)
=> false
irb(main):022> bob.heavier_than?(alice)
=> true
irb(main):023> alice.weight
(irb):23:in `<main>': protected method `weight' called for #<User:0x0000000103de9168 @name="Alice", @weight=50> (NoMethodError)
alice.weight
^^^^^^^
privateメソッドで上のコードを実行する
irb(main):001* class User
irb(main):002* attr_reader :name
irb(main):003*
irb(main):004* def initialize(name, weight)
irb(main):005* @name = name
irb(main):006* @weight = weight
irb(main):007* end
irb(main):008*
irb(main):009* def heavier_than?(other_user)
irb(main):010* other_user.weight < @weight
irb(main):011* end
irb(main):012*
irb(main):013* private
irb(main):014*
irb(main):015* def weight
irb(main):016* @weight
irb(main):017* end
irb(main):018> end
=> :weight
irb(main):019> alice = User.new("Alice",50)
=> #<User:0x000000010fae0a78 @name="Alice", @weight=50>
irb(main):020> bob = User.new("Bob", 60)
=> #<User:0x00000001136d9f48 @name="Bob", @weight=60>
irb(main):021> alice.heavier_than?(bob)
(irb):10:in `heavier_than?': private method `weight called for #<User:0x00000001136d9f48 @name="Bob", @weight=60> (NoMethodError)
other_user.weight < @weight
^^^^^^^
...
irb(main):022> bob.heavier_than?(alice)
(irb):10:in `heavier_than?': private method `weight called for #<User:0x000000010fae0a78 @name="Alice", @weight=50> (NoMethodError)
other_user.weight < @weight
^^^^^^^
...
irb(main):023> alice.weight
(irb):23:in `<main>': private method `weight' called for #<User:0x000000010fae0a78 @name="Alice", @weight=50> (NoMethodError)
alice.weight
^^^^^^^
- privateメソッドweightは読み込めない
特定のメソッドをprotectedに指定する
irb(main):033* class User
irb(main):034* attr_reader :name, :weight
irb(main):035* protected :weight
irb(main):036* def initialize(name, weight)
irb(main):037* @name = name
irb(main):038* @weight = weight
irb(main):039* end
irb(main):040*
irb(main):041* def heavier_than?(other_user)
irb(main):042* other_user.weight < @weight
irb(main):043* end
irb(main):044*
irb(main):045* def weight
irb(main):046* @weight
irb(main):047* end
irb(main):048> end
=> :weight
irb(main):049> alice = User.new("Alice",50)
=> #<User:0x0000000113425ce8 @name="Alice", @weight=50>
irb(main):050> bob = User.new("Bob", 60)
=> #<User:0x00000001134bed30 @name="Bob", @weight=60>
irb(main):051> alice.heavier_than?(bob)
=> false
上のコードをattr_reader :name
にしてみると
irb(main):018* class User
irb(main):019* attr_reader :name
irb(main):020* protected :weight
irb(main):021* def initialize(name, weight)
irb(main):022* @name = name
irb(main):023* @weight = weight
irb(main):024* end
irb(main):025*
irb(main):026* def heavier_than?(other_user)
irb(main):027* other_user.weight < @weight
irb(main):028* end
irb(main):029*
irb(main):030* def weight
irb(main):031* @weight
irb(main):032* end
irb(main):033> end
(irb):20:in `protected': undefined method `weight' for class `User' (NameError)
protected :weight
^^^^^^^^^
- アクセサメソッドで読み込まれなければprotectedは使えない
attr_writerにすると読み込まれないからエラーになる
irb(main):017* class User
irb(main):018* attr_writer :name, :weight
irb(main):019* protected :weight
irb(main):020* def initialize(name, weight)
irb(main):021* @name = name
irb(main):022* @weight = weight
irb(main):023* end
irb(main):024*
irb(main):025* def heavier_than?(other_user)
irb(main):026* other_user.weight < @weight
irb(main):027* end
irb(main):028*
irb(main):029* def weight
irb(main):030* @weight
irb(main):031* end
irb(main):032> end
(irb):19:in `protected': undefined method `weight' for class `User' (NameError)
protected :weight
^^^^^^^^^
...
irb(main):033* class User
irb(main):034* attr_reader :name, :weight
irb(main):035* protected :weight
irb(main):036* def initialize(name, weight)
irb(main):037* @name = name
irb(main):038* @weight = weight
irb(main):039* end
irb(main):040*
irb(main):041* def heavier_than?(other_user)
irb(main):042* other_user.weight < @weight
irb(main):043* end
irb(main):044*
irb(main):045* def weight
irb(main):046* @weight
irb(main):047* end
irb(main):048> end
=> :lifter:
感想
アクセサメソッドがおかしいとprotectedでエラーが起こる。
詳しくは理解していない。
weight=
が呼び出されるのでprotected :weight=
をするとエラーが出ない
irb(main):049* class User
irb(main):050* attr_writer :name, :weight
irb(main):051* protected :weight=
irb(main):052* def initialize(name, weight)
irb(main):053* @name = name
irb(main):054* @weight = weight
irb(main):055* end
irb(main):056*
irb(main):057* def heavier_than?(other_user)
irb(main):058* other_user.weight < @weight
irb(main):059* end
irb(main):060*
irb(main):061* def weight
irb(main):062* @weight
irb(main):063* end
irb(main):064> end
=> :weight