A cleaner way to pass a block or proc

Is there a cleaner way to implement my add_notifier method?

def add_notifier(notifier, &block)
if block_given?
@notifiers << block
else
@notifiers << notifier
end
end

def thump
raise ArgumentError, “You must add_notifier before you can notify”
if
@notifiers.empty?
@notifiers.each {|n| n.call }
end

Here’s how the method will be used.

hb.add_notifier nil do
puts “Notification1”
end

meth = lambda{ puts “notification2” }
hb.add_notifier(meth)

It just seems really unpretty to pass that nil when I want to pass just
the
block.

On Jun 25, 2008, at 5:48 PM, Tristin D. wrote:

def add_notifier(notifier, &block)
if block_given?
@notifiers << block
else
@notifiers << notifier
end
end

def add_notifier *argv, &block
argv.push block
@notifiers.push *argv
end

a @ http://codeforpeople.com/

On Thu, Jun 26, 2008, Tristin D. wrote:

It just seems really unpretty to pass that nil when I want to pass just the
block.

As an alternative to Ara’s suggestion:

def add_notifier( notifier = nil, &block )

You’ll need to change some of your internal logic as well to deal with
notifier being nil sometimes, but I like this better than using splats.
Personal taste.

Ben

Thanks Ben. That worked perfect. No other changes required in the class.
:slight_smile:

Here’s the final code. Maybe someone can get some use out of it. It
sends a
heartbeat (of your choosing) from your running ruby app at a given
interval.

class HeartBeat

attr_accessor :interval

def initialize(interval=120)
@interval = interval
@notifiers = Array.new
end

def add_notifier(notifier=nil, &block)
if block_given?
@notifiers << block
else
@notifiers << notifier
end
end

def thump
raise ArgumentError, “You must add_notifier before you can notify”
if
@notifiers.empty?
@notifiers.each {|n| n.call }
end

def start
Thread.abort_on_exception = true
@thread = Thread.new do
while true
thump
sleep @interval
end
end
end

def stop
@thread.terminate
end
end

Tristin D. wrote:

def add_notifier(notifier=nil, &block)
if block_given?
@notifiers << block
else
@notifiers << notifier
end
end

def add_notifier(notifier=nil, &block)
@notifiers << (block || notifier)
end

On Thu, Jun 26, 2008 at 3:04 AM, Joel VanderWerf
[email protected] wrote:

def add_notifier(notifier=nil, &block)
@notifiers << (block || notifier)
end

I think you could end up adding some nils with
this solution and the previous one, if I call:

Heartbeat.new.add_notifier

without any argument or block. Maybe you will
want to check it in the add_notifier method, or
at least handle it in the thump method, to avoid
calling the call method on nil. Maybe something like:

def add_notifier(notifier=nil, &block)
raise “Both nil” unless (notifier || block)
@notifiers << (block || notifier)
end

Jesus.

On Thu, Jun 26, 2008 at 3:04 AM, Joel VanderWerf
[email protected] wrote:

def add_notifier(notifier=nil, &block)
@notifiers << (block || notifier)
end

I would do it exactly as Jöel suggested above, however there is an
interesting alternative one might want to be aware of

def add_notfier notifier=nil
@notifiers << ( Proc::new rescue notifier)
end

Cheers
Robert


http://ruby-smalltalk.blogspot.com/


Les mêmes questions qu’on se pose
On part vers où et vers qui
Et comme indice pas grand-chose
Des roses et des orties.

Francis Cabrel

On Jun 26, 2008, at 4:39 AM, Robert D. wrote:

def add_notfier notifier=nil
@notifiers << ( Proc::new rescue notifier)
end

still adds nil if no args given though…

cheers.

a @ http://codeforpeople.com/

The final result.

def add_notifier(notifier=nil, &block)
raise ArgumentError, “Nil notifier. You must provide a Proc or a
block” if notifier.nil? && block.nil?
@notifiers << (notifier || block)
end

On Thu, Jun 26, 2008, Jess Gabriel y Galn wrote:

I think you could end up adding some nils with
this solution and the previous one, if I call:

Heartbeat.new.add_notifier

without any argument or block.

Right, this is why I suggested modifying the block to handle the nils :slight_smile:

Ben

On Thu, Jun 26, 2008 at 4:27 PM, ara.t.howard [email protected]
wrote:

cheers.

a @ http://codeforpeople.com/

we can deny everything, except that we have the possibility of being better.
simply reflect on that.
h.h. the 14th dalai lama

That is what OP wanted IIANM, the nils raise an exception later on.
Anyway I thought I had made it clear that your code is preferable but
I feel that teaching what Proc::new is about, is part of our job here
:wink:

Cheers
Robert

Can you explain it to me?

@notifiers << ( Proc::new rescue notifier)

On Thu, Jun 26, 2008 at 1:44 PM, Robert D. [email protected]

On Jun 26, 2008, at 12:44 PM, Robert D. wrote:

That is what OP wanted IIANM, the nils raise an exception later on.
Anyway I thought I had made it clear that your code is preferable but
I feel that teaching what Proc::new is about, is part of our job here
:wink:

ah. btw - i did not know about the argumentless Proc::new so you
achieved your goal :wink:

a @ http://codeforpeople.com/

Tristin D. wrote:

def add_notifier(notifier=nil, &block)
raise ArgumentError, “Nil notifier. You must provide a Proc or a
block” if notifier.nil? && block.nil?
@notifiers << (notifier || block)
end

A little less redundant…

def add_notifier(notifier=nil, &block)
@notifiers << (notifier || block || (
raise ArgumentError,
“Nil notifier. You must provide a Proc or a block”
))
end

On Thu, Jun 26, 2008 at 9:18 PM, ara.t.howard [email protected]
wrote:

your goal :wink:

Great I will spell it out for OP

Block::new takes implicitely the block you have passed to a method

irb(main):001:0> def a
irb(main):002:1> Proc::new.call
irb(main):003:1> end
=> nil
irb(main):004:0> a do 42 end
=> 42

However if there was no block passed to the method there will be an
error
irb(main):005:0> a
ArgumentError: tried to create Proc object without a block
from (irb):2:in new' from (irb):2:in a’

This error was caught by my rescue clause in the line

@notifiers << ( Proc::new rescue notifier )

But please again, Ara’s code is better idiomatic Ruby, but just in
case you stumble around Proc::new one day :wink:

HTH
Robert

http://ruby-smalltalk.blogspot.com/


AALST (n.) One who changes his name to be further to the front
D.Adams; The Meaning of LIFF