Last active
August 29, 2015 14:03
-
-
Save tooky/5673afd4599b02aef0eb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'minitest/autorun' | |
class Foo | |
attr_accessor :a | |
def initialize | |
@a = :unchanged | |
end | |
# call 'a' with explicit 'self' as receiver | |
def b; self.a; end | |
def b=(v); self.a = v; end | |
# call 'a' with implicit 'self' as receiver | |
def c; a; end | |
def c=(v); a = v; end | |
def value | |
@a | |
end | |
end | |
class ProtectedFoo < Foo | |
protected :a, :a= | |
end | |
class PrivateFoo < Foo | |
private :a, :a= | |
end | |
class PublicVisibilityTest < Minitest::Test | |
def setup | |
@foo = Foo.new | |
end | |
def test_reader_explicit_receiver_succeeds | |
assert_equal :unchanged, @foo.a | |
end | |
def test_writer_explicit_receiver_succeeds | |
@foo.a = 4 | |
assert_equal 4, @foo.value | |
end | |
def test_reader_explicit_self_receiver_succeeds | |
assert_equal :unchanged, @foo.b | |
end | |
def test_writer_explicit_self_receiver_succeeds | |
@foo.b = 4 | |
assert_equal 4, @foo.value | |
end | |
def test_reader_implicit_self_receiver_succeeds | |
assert_equal :unchanged, @foo.c | |
end | |
def test_writer_implicit_self_receiver_succeeds_but_does_nothing | |
@foo.c = 4 | |
assert_equal :unchanged, @foo.value | |
end | |
end | |
class ProtectedVisibilityTest < Minitest::Test | |
def setup | |
@foo = ProtectedFoo.new | |
end | |
def test_reader_explicit_receiver_fails | |
assert_raises(NoMethodError) do | |
@foo.a | |
end | |
end | |
def test_writer_explicit_receiver_fails | |
assert_raises(NoMethodError) do | |
@foo.a = 4 | |
end | |
assert_equal :unchanged, @foo.value | |
end | |
def test_reader_explicit_self_receiver_succeeds | |
assert_equal :unchanged, @foo.b | |
end | |
def test_writer_explicit_self_receiver_succeeds | |
@foo.b = 4 | |
assert_equal 4, @foo.value | |
end | |
def test_reader_implicit_self_receiver_succeeds | |
assert_equal :unchanged, @foo.c | |
end | |
def test_writer_implicit_self_receiver_succeeds_but_does_nothing | |
@foo.c = 4 | |
assert_equal :unchanged, @foo.value | |
end | |
end | |
class PrivateVisibilityTest < Minitest::Test | |
def setup | |
@foo = PrivateFoo.new | |
end | |
def test_reader_explicit_receiver_fails | |
assert_raises(NoMethodError) do | |
@foo.a | |
end | |
end | |
def test_writer_explicit_receiver_fails | |
assert_raises(NoMethodError) do | |
@foo.a = 4 | |
end | |
assert_equal :unchanged, @foo.value | |
end | |
def test_reader_explicit_self_receiver_fails | |
assert_raises(NoMethodError) do | |
@foo.b | |
end | |
end | |
def test_writer_explicit_self_receiver_fails | |
assert_raises(NoMethodError) do | |
@foo.b = 4 | |
end | |
assert_equal :unchanged, @foo.value | |
end | |
def test_reader_implicit_self_receiver_succeeds | |
assert_equal :unchanged, @foo.c | |
end | |
def test_writer_implicit_self_receiver_succeeds_but_does_nothing | |
@foo.c = 4 | |
assert_equal :unchanged, @foo.value | |
end | |
end | |
# Run options: --seed 18945 | |
# | |
# Running: | |
# | |
# ................F. | |
# | |
# Finished in 0.002823s, 6376.1955 runs/s, 7084.6617 assertions/s. | |
# | |
# 1) Failure: | |
# PrivateVisibilityTest#test_writer_explicit_self_receiver_fails [visibility_test.rb:126]: | |
# NoMethodError expected but nothing was raised. | |
# | |
# 18 runs, 20 assertions, 1 failures, 0 errors, 0 skips |
@JEG2 thanks.
It started as a discussion about why ruby issues warnings for private attr_*
.
We'd assumed that the only way to send a private writer message would be using #send
.
Of course it makes sense to make an exception for the =
operator – which then leaves us back with the question about the warnings!
I'm not a fan of that warning. I avoid it by doing what you showed in the thread and specifically naming what I want to be private
. I'm not sure why the warning exists, sorry.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
self
, and onlyself
, is allowed on private writer methods. This is a needed special exception to the rules because justa = 42
is a local variable assignment, not a method call. Line 16 of your example does not calla=()
.