Skip to content

Commit

Permalink
Emit a performance warning when OpenStruct is used (#56)
Browse files Browse the repository at this point in the history
The OpenStruct documentation clearly state that it shouldn't
be used when performance is expected.

Ruby 3.3 introduce a new category of warnings that is silenced
by default: performance.

The expected use case is to enable this warning when looking
for potential performance issues within an application.

As such I think it would make sense to emit a performance warning
when OpenStruct is used, as it may help pinpoint that a dependency
rely on it, etc.

Co-authored-by: Jean Boussier <jean.boussier@gmail.com>
  • Loading branch information
casperisfine and byroot authored Sep 29, 2023
1 parent ba2c352 commit 5826e12
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 0 deletions.
12 changes: 12 additions & 0 deletions lib/ostruct.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,14 @@
class OpenStruct
VERSION = "0.5.5"

HAS_PERFORMANCE_WARNINGS = begin
Warning[:performance]
true
rescue NoMethodError, ArgumentError
false
end
private_constant :HAS_PERFORMANCE_WARNINGS

#
# Creates a new OpenStruct object. By default, the resulting OpenStruct
# object will have no attributes.
Expand All @@ -124,6 +132,10 @@ class OpenStruct
# data # => #<OpenStruct country="Australia", capital="Canberra">
#
def initialize(hash=nil)
if HAS_PERFORMANCE_WARNINGS && Warning[:performance]
warn "OpenStruct use is discouraged for performance reasons", uplevel: 1, category: :performance
end

if hash
update_to_values!(hash)
else
Expand Down
1 change: 1 addition & 0 deletions ostruct.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ Gem::Specification.new do |spec|

spec.add_development_dependency "bundler"
spec.add_development_dependency "rake"
spec.add_development_dependency "test-unit"
end
19 changes: 19 additions & 0 deletions test/ostruct/test_ostruct.rb
Original file line number Diff line number Diff line change
Expand Up @@ -412,4 +412,23 @@ def test_class
assert_equal('my-class', os.class)
assert_equal(OpenStruct, os.class!)
end

has_performance_warnings = begin
Warning[:performance]
true
rescue NoMethodError, ArgumentError
false
end

if has_performance_warnings
def test_performance_warning
assert_in_out_err(
%w(-Ilib -rostruct -w -W:performance -e) + ['OpenStruct.new(a: 1)'],
"",
[],
["-e:1: warning: OpenStruct use is discouraged for performance reasons"],
success: true,
)
end
end
end

0 comments on commit 5826e12

Please sign in to comment.