Skip to content

Commit

Permalink
Mention block form of Struct.new in Style/StructInheritance
Browse files Browse the repository at this point in the history
As the documentation for `Struct` recommends using the block
form over inheriting, I think it is worth mentioning it.

> If a block is given it will be evaluated in the context of
StructClass, passing the created class as a parameter

> This is the recommended way to customize a struct.

Adjust examples in the documentation and add a test which uses
the block form.
  • Loading branch information
XrXr committed Apr 1, 2019
1 parent a1dd70c commit 5658046
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 5 deletions.
12 changes: 10 additions & 2 deletions lib/rubocop/cop/style/struct_inheritance.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,20 @@ module Style
# @example
# # bad
# class Person < Struct.new(:first_name, :last_name)
# def age
# 42
# end
# end
#
# # good
# Person = Struct.new(:first_name, :last_name)
# Person = Struct.new(:first_name, :last_name) do
# def age
# 42
# end
# end
class StructInheritance < Cop
MSG = "Don't extend an instance initialized by `Struct.new`.".freeze
MSG = "Don't extend an instance initialized by `Struct.new`. " \
'Use a block to customize the struct.'.freeze

def on_class(node)
_name, superclass, _body = *node
Expand Down
9 changes: 8 additions & 1 deletion manual/cops_style.md
Original file line number Diff line number Diff line change
Expand Up @@ -5954,10 +5954,17 @@ This cop checks for inheritance from Struct.new.
```ruby
# bad
class Person < Struct.new(:first_name, :last_name)
def age
42
end
end

# good
Person = Struct.new(:first_name, :last_name)
Person = Struct.new(:first_name, :last_name) do
def age
42
end
end
```

### References
Expand Down
14 changes: 12 additions & 2 deletions spec/rubocop/cop/style/struct_inheritance_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
it 'registers an offense when extending instance of Struct' do
expect_offense(<<-RUBY.strip_indent)
class Person < Struct.new(:first_name, :last_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Don't extend an instance initialized by `Struct.new`.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Don't extend an instance initialized by `Struct.new`. Use a block to customize the struct.
end
RUBY
end

it 'registers an offense when extending instance of Struct with do ... end' do
expect_offense(<<-RUBY.strip_indent)
class Person < Struct.new(:first_name, :last_name) do end
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Don't extend an instance initialized by `Struct.new`.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Don't extend an instance initialized by `Struct.new`. Use a block to customize the struct.
end
RUBY
end
Expand All @@ -36,4 +36,14 @@ class Person < DelegateClass(Animal)
it 'accepts assignment to Struct.new' do
expect_no_offenses('Person = Struct.new(:first_name, :last_name)')
end

it 'accepts assignment to block form of Struct.new' do
expect_no_offenses(<<-RUBY.strip_indent)
Person = Struct.new(:first_name, :last_name) do
def age
42
end
end
RUBY
end
end

0 comments on commit 5658046

Please sign in to comment.