Class: RestEasy::Meta
- Inherits:
-
Object
- Object
- RestEasy::Meta
- Defined in:
- lib/rest_easy/meta.rb
Instance Method Summary collapse
-
#initialize(new_record: false, saved: false, **defaults) ⇒ Meta
constructor
A new instance of Meta.
- #method_missing(name, *args) ⇒ Object
- #new? ⇒ Boolean
-
#respond_to_missing?(name, include_private = false) ⇒ Boolean
method_missinganswers to any name, but this must not, because callers routinely ask an object what it can do before calling it — Ruby's own coercion probes (to_hashon double-splat,to_ary,to_str), serialisation hooks (marshal_dump,init_with), and any library that duck-types withrespond_to?. - #saved? ⇒ Boolean
Constructor Details
#initialize(new_record: false, saved: false, **defaults) ⇒ Meta
Returns a new instance of Meta.
5 6 7 |
# File 'lib/rest_easy/meta.rb', line 5 def initialize(new_record: false, saved: false, **defaults) @data = { new: new_record, saved: saved, **defaults } end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args) ⇒ Object
17 18 19 20 21 22 23 24 25 26 |
# File 'lib/rest_easy/meta.rb', line 17 def method_missing(name, *args) key = name.to_s if key.end_with?("=") @data[key.chomp("=").to_sym] = args.first elsif key.end_with?("?") !!@data[key.chomp("?").to_sym] else @data[name.to_sym] end end |
Instance Method Details
#new? ⇒ Boolean
9 10 11 |
# File 'lib/rest_easy/meta.rb', line 9 def new? @data[:new] end |
#respond_to_missing?(name, include_private = false) ⇒ Boolean
method_missing answers to any name, but this must not, because callers
routinely ask an object what it can do before calling it — Ruby's own
coercion probes (to_hash on double-splat, to_ary, to_str),
serialisation hooks (marshal_dump, init_with), and any library that
duck-types with respond_to?. Claiming those hands the caller the nil
that method_missing returns for an unknown key as though it were an
answer.
Bare getters are therefore claimed only for keys actually held. Setters
and predicates are claimed unconditionally: writing is how a key comes
into existence, and an unset predicate is meaningfully false. No core
Ruby probe uses those two shapes — though library-level duck-typing can,
and ActiveSupport's acts_like?(:date) asking for acts_like_date? is
a known false positive. Closing it properly means declaring meta keys
up front, which is a breaking change — see issue #7.
@data is guarded because respond_to? must never raise, and Ruby
allocates an instance before initialising it: Psych's revive probes
init_with on a bare allocation, and so does Marshal.load on a
payload written before this fix.
This under-claims a bare getter for a key that was never set, which
method_missing still answers with nil. Reconciling the two halves
means declaring meta keys up front, and that is a 2.0 — see issue #7.
63 64 65 66 67 68 |
# File 'lib/rest_easy/meta.rb', line 63 def respond_to_missing?(name, include_private = false) return true if ACCESSOR_PATTERN.match?(name.to_s) return super unless @data @data.key?(name.to_sym) || super end |
#saved? ⇒ Boolean
13 14 15 |
# File 'lib/rest_easy/meta.rb', line 13 def saved? @data[:saved] end |