Skip to content

Commit a12f44f

Browse files
authored
Merge pull request #67 from casperisfine/ruby-3.0
Ruby ruby-head (3.0.0-dev) support
2 parents 630df4c + 32e1508 commit a12f44f

File tree

1 file changed

+45
-22
lines changed

1 file changed

+45
-22
lines changed

lib/recursive_open_struct.rb

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,16 @@ def initialize(hash=nil, passed_options={})
3939
@sub_elements = {}
4040
end
4141

42-
def initialize_copy(orig)
43-
super
4442

45-
# deep copy the table to separate the two objects
46-
@table = @deep_dup.call(orig.instance_variable_get(:@table))
47-
# Forget any memoized sub-elements
48-
@sub_elements = {}
43+
if OpenStruct.public_instance_methods.include?(:initialize_copy)
44+
def initialize_copy(orig)
45+
super
46+
47+
# deep copy the table to separate the two objects
48+
@table = @deep_dup.call(@table)
49+
# Forget any memoized sub-elements
50+
@sub_elements = {}
51+
end
4952
end
5053

5154
def to_h
@@ -56,6 +59,19 @@ def to_h
5659
# itself to be a "kind of" Hash.
5760
alias_method :to_hash, :to_h
5861

62+
# Continue supporting older rubies -- JRuby 9.1.x.x is still considered
63+
# stable, but is based on Ruby
64+
# 2.3.x and so uses :modifiable instead of :modifiable?. Furthermore, if
65+
# :modifiable is private, then make :modifiable? private too.
66+
if !OpenStruct.private_instance_methods.include?(:modifiable?)
67+
if OpenStruct.private_instance_methods.include?(:modifiable)
68+
alias_method :modifiable?, :modifiable
69+
elsif OpenStruct.public_instance_methods.include?(:modifiable)
70+
alias_method :modifiable?, :modifiable
71+
private :modifiable?
72+
end
73+
end
74+
5975
def [](name)
6076
key_name = _get_key_from_table_(name)
6177
v = @table[key_name]
@@ -69,11 +85,19 @@ def [](name)
6985
end
7086
end
7187

72-
def []=(name, value)
73-
key_name = _get_key_from_table_(name)
74-
tbl = modifiable? # Ensure we are modifiable
75-
@sub_elements.delete(key_name)
76-
tbl[key_name] = value
88+
if private_instance_methods.include?(:modifiable?) || public_instance_methods.include?(:modifiable?)
89+
def []=(name, value)
90+
key_name = _get_key_from_table_(name)
91+
tbl = modifiable? # Ensure we are modifiable
92+
@sub_elements.delete(key_name)
93+
tbl[key_name] = value
94+
end
95+
else
96+
def []=(name, value)
97+
key_name = _get_key_from_table_(name)
98+
@table[key_name] = value # raises if self is frozen in Ruby 3.0
99+
@sub_elements.delete(key_name)
100+
end
77101
end
78102

79103
# Makes sure ROS responds as expected on #respond_to? and #method requests
@@ -82,17 +106,6 @@ def respond_to_missing?(mid, include_private = false)
82106
@table.key?(mname) || super
83107
end
84108

85-
# Continue supporting older rubies -- JRuby 9.1.x.x is still considered
86-
# stable, but is based on Ruby
87-
# 2.3.x and so uses :modifiable instead of :modifiable?. Furthermore, if
88-
# :modifiable is private, then make :modifiable? private too.
89-
if !OpenStruct.private_instance_methods.include?(:modifiable?)
90-
alias_method :modifiable?, :modifiable
91-
if OpenStruct.private_instance_methods.include?(:modifiable)
92-
private :modifiable?
93-
end
94-
end
95-
96109
# Adapted implementation of method_missing to accommodate the differences
97110
# between ROS and OS.
98111
def method_missing(mid, *args)
@@ -155,6 +168,16 @@ def delete_field(name)
155168

156169
private
157170

171+
unless OpenStruct.public_instance_methods.include?(:initialize_copy)
172+
def initialize_dup(orig)
173+
super
174+
# deep copy the table to separate the two objects
175+
@table = @deep_dup.call(@table)
176+
# Forget any memoized sub-elements
177+
@sub_elements = {}
178+
end
179+
end
180+
158181
def _get_key_from_table_(name)
159182
return name.to_s if @table.has_key?(name.to_s)
160183
return name.to_sym if @table.has_key?(name.to_sym)

0 commit comments

Comments
 (0)