Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Safely prepend Publisher initializers
This change alters `Publisher` and `EventExaminer` to use `Module#prepend` to inject their initializers into the call chain. The intention is to allow classes that include `Publisher` to include their own `#initialize` method that still preserves the behavior of `Publisher#initialize`. Consider: module Foo def initialize(*args) puts "Foo: #{args.inspect}" super end end class A include Foo def initialize(arg) puts "A: #{arg}" end end class B prepend Foo def initilaize(arg) puts "B: #{arg}" end end In the case of `A`, since `Foo` is attached via `#include`, the initializer defined in `Foo` is essentially ignored: irb(main):046:0> A.new :foo A: :foo => #<A:0x007fae191b4a08> However, in `B`, since `Foo` is attacted via `#prepend`, the initializer actually ends up behaving as if it were a superclass method of `B#initialize`: irb(main):045:0> B.new :foo Foo: [:foo] B: :foo => #<B:0x007fae191bca28> This `#prepend` trick works well for your initializers that actually want to inject behavior during initialization, but ultimately stay out of the way of any `#initialize` defined by the consuming class. I ran into this when I tried including `Publisher` in a class that had an initializer with arguments; I was seeing a "1 for 0" `ArgumentError`. When I dug into the proofs, I noticed that `ReplayTest` does not actually have an `#initialize` method of its' own. My initial effort at producing a failing test was to subclass `ReplayTest` within the specific proof for testing custom initializers; however, subclassing overrode the faulty behavior and thus did not produce a failing test. Instead, I added a constructor argument to override the `pkey` attribute. It seemed like the least janky way to introduce a failing test. If I made the proofs worse, I can try and think of a better way to expose the problem I was trying to solve. It's worth noting that this change would break ruby 1.9, which does not have `Module#prepend`.
- Loading branch information