Skip to content

Commit

Permalink
Mention block form of Struct.new in Style/StructInheritance (#6875)
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 authored and bbatsov committed Apr 4, 2019
1 parent 355e9e5 commit 3bcbed1
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 6 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
* [#6854](https://github.com/rubocop-hq/rubocop/pull/6854): Mark Rails/LexicallyScopedActionFilter as unsafe and document risks. ([@urbanautomaton][])
* [#5977](https://github.com/rubocop-hq/rubocop/issues/5977): Warn for Performance Cops. ([@koic][])
* [#6637](https://github.com/rubocop-hq/rubocop/issues/6637): Move `LstripRstrip` from `Performance` to `Style` department and rename it to `Strip`. ([@anuja-joshi][])
* [#6875](https://github.com/rubocop-hq/rubocop/pull/6875): Mention block form of `Struct.new` in ` Style/StructInheritance`. ([@XrXr][])

## 0.66.0 (2019-03-18)

Expand Down Expand Up @@ -3903,4 +3904,5 @@
[@ericsullivan]: https://github.com/ericsullivan
[@aeroastro]: https://github.com/aeroastro
[@anuja-joshi]: https://github.com/anuja-joshi
[@thomthom]: https://github.com/thomthom
[@XrXr]: https://github.com/XrXr
[@thomthom]: https://github.com/thomthom
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 @@ -5955,10 +5955,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 3bcbed1

Please sign in to comment.