views:

69

answers:

3

I have a great number of methods like this:

def enableMotors
  @posIface.Lock 1
  @posIface.data.cmdEnableMotors = 1
  @posIface.Unlock
end

def goTo (pos)
  @posIface.Lock 1
  @posIface.data.cmdVelocity.pos = pos
  @posIface.Unlock
end

I would like to create functionality to :before_filter and :after_filter or any other way I can keep this code as DRY as possible. I dont want to depend on Rails or other heavy stuff only for this.

+6  A: 

Do you really need a full :before :after callback system or is this enough for you?

def with_lock(&block)
  @posIface.Lock 1
  yield
  @posIface.Unlock
end

def enableMotors
  with_lock { @posIface.data.cmdEnableMotors = 1 }
end

def goTo (pos)
  with_lock { @posIface.data.cmdVelocity.pos = pos }
end
Simone Carletti
+2  A: 

To expand on weppos's answer, making use of yield and code blocks looks like what is necessary and DRY here. Since @posIface.data is used in both blocks, you could do the following to DRY it further:

def with_lock(&block)
  @posIface.Lock 1
  yield @posIface.data
  @posIface.Unlock
end

def enableMotors
  with_lock { |obj| obj.cmdEnableMotors = 1 }
end

def goTo (pos)
  with_lock { |obj| obj.cmdVelocity.pos = pos }
end
Sarah Vessels
A: 
def self.locked_def(name, &b)
   instance_eval do
     define_method(name) do
       @posIface.Lock 1
       b.call
       @posIface.UnLock
      end
   end
 end

 locked_def :pos { @posIface.data.cmdVelocity.pos = pos }

I think that will do it (not sure off the top of my head about the block call).

weppos's answer is a better solution though.

Ben Hughes