Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 771
TheDelChop Avatar asked May 10 '12 19:05

TheDelChop


1 Answers

Try

super(*args,&nil)

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

like image 130
Frederick Cheung Avatar answered Nov 14 '22 11:11

Frederick Cheung