Commit f1e2ce5
committed
Base: Replace regexps in
Prior to this commit, the regular expressions used in both
`method_missing` and `respond_to_missing` were similar, but had slight
variations. That resulted in unknown attributes being able to be written
to through methods "did not respond to" (like `send("#{attr_name}=",
value)`). Similarly, the `?`-suffixed predicate methods would return the
same way when invoked.
Without the implementation changes, the following tests introduced in
this commit fail:
```
1) Failure:
BaseTest#test_respond_to_unknown_attribute_writer [test/cases/base_test.rb:967]:
Expected #<Post:0x0000000120cb7958 @attributes={}, @prefix_options={}, @persisted=false> (Post) to respond to #unknown_attribute=.
```
This commit's changes replace the regular expressions with explicit
[String#end_with?][]. Originally (in [4179e98][] on May 4, 2007!), the
implementation was based on String comparison, but was eventually
replaced with a Regular-expression based implementation in [c7629a6][]
(on on Nov 9, 2009). The commit message for `c7629a6` cited <q>reliance
on string access core extension</q>. In the intervening years, Ruby's
standard library String implementation added `end_with?`, so the core
extensions mentioned in the message are no longer necessary in modern
Ruby versions.
Considerations
---
This change introduces subtle behavior changes. Whether or not it fixes
a bug or introduces a breaking change might be open to interpretation.
Conventions recommend that `respond_to?` and `method_missing` *should*
remain synchronized in what they consider inside and outside of a class
interface. Supporting the method invocations for `=` and `?` suffixed
methods without providing indications of that support when asked by
callers deviates from that convention.
In order to respond to `=`-suffixed writers and `?`-suffixed predicates,
the prior implementation required that the attributes being written to
or queried must have already been assigned to the internal `@attributes`
hash. That means that a `method_missing`-triggered write must've
pre-dated the `respond_to?` invocation.
Whether or not this is coincidental or intentional is a question best
asked of the historical authors and creators of the gem.
Ignoring intent, this commit proposes that both `respond_to?` and
`method_missing` communicate support for `=`- and `?`-suffixed methods
regardless of whether or not they've been written already.
[String#end_with?]: https://ruby-doc.org/3.4.1/String.html#method-i-end_with-3F
[4179e98]: 4179e98
[c7629a6]: c7629a6method_missing and respond_to_missing
1 parent b549319 commit f1e2ce5
2 files changed
Lines changed: 36 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1653 | 1653 | | |
1654 | 1654 | | |
1655 | 1655 | | |
1656 | | - | |
| 1656 | + | |
1657 | 1657 | | |
1658 | 1658 | | |
1659 | 1659 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
960 | 960 | | |
961 | 961 | | |
962 | 962 | | |
963 | | - | |
| 963 | + | |
| 964 | + | |
| 965 | + | |
| 966 | + | |
| 967 | + | |
| 968 | + | |
| 969 | + | |
| 970 | + | |
| 971 | + | |
| 972 | + | |
| 973 | + | |
| 974 | + | |
| 975 | + | |
| 976 | + | |
| 977 | + | |
| 978 | + | |
| 979 | + | |
| 980 | + | |
| 981 | + | |
| 982 | + | |
| 983 | + | |
| 984 | + | |
| 985 | + | |
| 986 | + | |
| 987 | + | |
| 988 | + | |
| 989 | + | |
| 990 | + | |
| 991 | + | |
| 992 | + | |
| 993 | + | |
| 994 | + | |
| 995 | + | |
| 996 | + | |
| 997 | + | |
964 | 998 | | |
965 | 999 | | |
966 | 1000 | | |
| |||
0 commit comments