This allows for on_* to be defined by defining the corresponding instance method

directly.  Prior to this fix, doing this will result in "SystemStackError: stack
level too deep".

Example
module RedStorm
  module Examples
    class SplitSentenceBolt < DSL::Bolt
      def on_receive(tuple)
        tuple[0].split(' ').map{|w| [w]}
      end
    end
  end
end
This commit is contained in:
Ian Smith 2014-07-28 14:40:31 -07:00 committed by R. Tyler Croy
parent cf723b2136
commit 5d7debdf16
2 changed files with 54 additions and 10 deletions

View File

@ -35,20 +35,26 @@ module RedStorm
self.receive_options.merge!(options)
# indirecting through a lambda defers the method lookup at invocation time
# and the performance penalty is negligible
body = block_given? ? on_receive_block : lambda{|tuple| self.send((method_name || :on_receive).to_sym, tuple)}
define_method(:on_receive, body)
unless self.instance_methods.include?(:on_receive)
# indirecting through a lambda defers the method lookup at invocation time
# and the performance penalty is negligible
body = block_given? ? on_receive_block : lambda{|tuple| self.send((method_name || :on_receive).to_sym, tuple)}
define_method(:on_receive, body)
end
end
def self.on_init(method_name = nil, &on_init_block)
body = block_given? ? on_init_block : lambda {self.send((method_name || :on_init).to_sym)}
define_method(:on_init, body)
unless self.instance_methods.include?(:on_init)
body = block_given? ? on_init_block : lambda {self.send((method_name || :on_init).to_sym)}
define_method(:on_init, body)
end
end
def self.on_close(method_name = nil, &on_close_block)
body = block_given? ? on_close_block : lambda {self.send((method_name || :on_close).to_sym)}
define_method(:on_close, body)
unless self.instance_methods.include?(:on_close)
body = block_given? ? on_close_block : lambda {self.send((method_name || :on_close).to_sym)}
define_method(:on_close, body)
end
end
# DSL instance methods

View File

@ -105,6 +105,13 @@ describe RedStorm::SimpleBolt do
end
describe "with block argument" do
it "should set the on_receive method to the block" do
class Bolt1 < RedStorm::SimpleBolt
on_receive { 'a block value' }
end
Bolt1.new.on_receive.should == 'a block value'
end
it "should parse without options" do
class Bolt1 < RedStorm::SimpleBolt
@ -218,6 +225,18 @@ describe RedStorm::SimpleBolt do
end
describe "with default method" do
it "should use the default method" do
CUSTOM_RECEIVE_OPTIONS = {:emit => false, :ack => false, :anchor => true}
class Bolt1 < RedStorm::SimpleBolt
on_receive CUSTOM_RECEIVE_OPTIONS
def on_receive ; 'a method value' ; end
end
Bolt1.new.on_receive.should == 'a method value'
Bolt1.receive_options.should == CUSTOM_RECEIVE_OPTIONS
end
it "should parse without options" do
class Bolt1 < RedStorm::SimpleBolt
@ -290,10 +309,19 @@ describe RedStorm::SimpleBolt do
bolt.should_receive(:test_method)
bolt.prepare(nil, nil, nil)
end
it "should use a predefined method" do
class Bolt1 < RedStorm::SimpleBolt
def on_init
'a method value'
end
end
Bolt1.new.on_init.should == 'a method value'
end
end
describe "on_close statement" do
it "should parse block argument" do
class Bolt1 < RedStorm::SimpleBolt
on_close {self.test_block_call}
@ -313,6 +341,16 @@ describe RedStorm::SimpleBolt do
bolt.should_receive(:test_method)
bolt.cleanup
end
it "should use a predefined method" do
class Bolt1 < RedStorm::SimpleBolt
def on_close
'a method value'
end
end
Bolt1.new.on_close.should == 'a method value'
end
end
describe "configure statement" do
@ -701,4 +739,4 @@ describe RedStorm::SimpleBolt do
end
end
end
end