Search code examples
ruby-on-railsrubyactive-attr

Scrubbing a block from a call to super


I'm working with ActiveAttr which gives you that nice initialize via block option:

person = Person.new() do |p|
  p.first_name = 'test'
  p.last_name = 'man'
end

However, in a specific class that include ActiveAttr::Model, I want to bypass this functionality since I want to use the block for something else. So here we go:

class Imperator::Command
 include ActiveAttr::Model
end


class MyCommand < Imperator::Command

  def initialize(*args, &block)
    @my_block = block

    super(*args)
  end
end

This fails miserably, because the block still gets passed up the chain, and eventually inside of ActiveAttr, this code gets run:

def initialize(*)
  super
  yield self if block_given?
end

So if my call looks like so:

MyCommand.new() { |date| date.advance(month: 1) }

it fails as follows:

NoMethodError: undefined method `advance' for #<MyCommand:0x007fe432c4fb80>

since MyCommand has no method :advance it the call to MyCommand obviously fails.

So my question is this, is there a way that I can remove the block from the method signature before I call super again, so that the block travels no further than my overridden initializer?


Solution

  • Try

    super(*args,&nil)
    

    The & makes ruby use nil as the block and ruby seems smart enough to realise this means no block.