Created
July 31, 2012 06:05
-
-
Save mboeh/3214170 to your computer and use it in GitHub Desktop.
#dup and #clone are so rude!
This file contains hidden or 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
class Object | |
private :dup | |
private :clone | |
private :freeze | |
end | |
module ValueObject | |
def self.included(into) | |
into.send :public, :dup | |
into.send :public, :clone | |
into.send :public, :freeze | |
end | |
end | |
[Array, Hash, String].each do |value_class| | |
value_class.send :include, ValueObject | |
end | |
module ValueStruct | |
def initialize(*a) | |
super(*a) | |
include ValueObject | |
end | |
end | |
Struct.send :include, ValueStruct | |
if $0 == __FILE__ | |
require 'test/unit' | |
class NoDupTest < Test::Unit::TestCase | |
def test_object_nodup | |
o = Object.new | |
assert_raise NoMethodError do | |
o.dup | |
end | |
assert_raise NoMethodError do | |
o.clone | |
end | |
end | |
def test_own_class_nodup | |
c = Class.new | |
o = c.new | |
assert_raise NoMethodError do | |
o.dup | |
end | |
assert_raise NoMethodError do | |
o.clone | |
end | |
end | |
def test_value_class_dup | |
c = Class.new do | |
include ValueObject | |
end | |
assert_nothing_raised do | |
c.dup | |
end | |
end | |
def test_array_dup | |
a = [:yes] | |
assert_equal a.dup.first, :yes | |
end | |
def test_hash_dup | |
h = {:yes => true} | |
assert h.dup[:yes] | |
end | |
def test_string_dup | |
s = "abc" | |
assert_equal s.dup, "abc" | |
end | |
# FIXME: How can I get ValueObject into every generated Struct class? | |
def test_struct_dup | |
s = Struct.new(:a, :b, :c) | |
o = s.new(1, 2, 3) | |
assert_equal o.dup.a, 1 | |
end | |
end | |
end |
This file contains hidden or 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
# #dup and #clone break encapsulation | |
class Box | |
def initialize(size) | |
@size = size | |
@items = [] | |
end | |
def <<(item) | |
if full? | |
raise "box is full" | |
else | |
@items << item | |
end | |
end | |
def full? | |
@items.length == @size | |
end | |
end | |
box1 = Box.new 3 | |
box1 << :fork | |
box1 << :knife | |
box2 = box1.dup | |
box2 << :spoon | |
box1 << :napkin # raises "box is full" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment