def with(event_class: self.class, **attributes)
      if self.class != Event && !attributes[:type].nil? && attributes[:type] != type
        raise Error, 'When using typed events change the type by changing the event class.'
      end

      event_class.new(**to_h.merge!(attributes))
    end
def with(event_class: self.class, **attributes)
      if self.class != Event && !attributes[:type].nil? && attributes[:type] != type
        raise Error, 'When using typed events change the type by changing the event class.'
      end

      event_class.new(**to_h.merge!(attributes))
    end
create a new event identical to the old event except for the provided changes

 @param attributes [Hash]
 @return Event
 @example
     old_event = EventSourcery::Event.new(type: "item_added", causation_id: nil)
     new_event = old_event.with(causation_id: "05781bd6-796a-4a58-8573-b109f683fd99")

     new_event.type # => "item_added"
     new_event.causation_id # => "05781bd6-796a-4a58-8573-b109f683fd99"

     old_event.type # => "item_added"
     old_event.causation_id # => nil

     # Of course, with can accept any number of event attributes:

     new_event = old_event.with(id: 42, version: 77, body: { 'attr' => 'value' })

     # When using typed events you can also override the event class:

     new_event = old_event.with(event_class: ItemRemoved)
     new_event.type # => "item_removed"
     new_event.class # => ItemRemoved