Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent `super` from yielding

Tags:

ruby

I have a class Duck with an initialize method that yields to a block:

class Duck
  def initialize()
    if block_given?
      yield(self)
    end
  end
end

and a class TalkingDuck that greets the programmer when it is initialized.

class TalkingDuck < Duck
  def initialize()
    super()
    puts 'I am a duck'
  end
end

When I call the constructor TalkingDuck.new with a block, I don't want this block to be executed. This:

TalkingDuck.new { puts 'Quack' }

should only print I am a duck, but not Quack. How can I prevent the block from being executed?

like image 857
DarkWiiPlayer Avatar asked Jun 04 '18 07:06

DarkWiiPlayer


1 Answers

Ruby implicitly passes the arguments and the block of the current method to super. With arguments, that can be avoided by explicitly calling super with no arguments (super()). The same thing can be done with blocks. A block can be passed to a method with &:

greet = proc { puts 'hi' }
do_some_stuff(&greet)

you can explicitly avoid passing a block with &nil. In this case, this means you can change the initialize method of TalkingDuck to:

def initialize()
  super(&nil)
  puts 'I am a duck'
end

and it will explicitly discard any given block and not pass it further up to super, but you can still handle the block yourself inside the method.

like image 125
DarkWiiPlayer Avatar answered Nov 07 '22 16:11

DarkWiiPlayer