Best DRY way to write bang versions of methods?

I've been wondering about the best way to quickly create a "bang"
version of a method (specifically one which overwrites self). Is there a
better DRY approach than the below?
I guess that there's probably a way to input a list of methods as
symbols and output bang versions of each as new methods, but at the
moment I'm more interested in the wording of the bang method itself.

This is the best I can come up with (in pseudo-code):

def test( arg1, arg2, arg3=true )
  #Do stuff with the args that returns a value
end

def test!(*p)
  replace test(*p)
end

···

--
Posted via http://www.ruby-forum.com/.

Hi...

IMHO sometimes this is useful:

def foo(something)
  dup.foo!(something)
end

def foo!(something)
  # do the work...
end

e.

···

On Thu, Feb 14, 2013 at 1:06 PM, Joel Pearson <lists@ruby-forum.com> wrote:

I've been wondering about the best way to quickly create a "bang"
version of a method (specifically one which overwrites self). Is there a
better DRY approach than the below?
I guess that there's probably a way to input a list of methods as
symbols and output bang versions of each as new methods, but at the
moment I'm more interested in the wording of the bang method itself.

This is the best I can come up with (in pseudo-code):

def test( arg1, arg2, arg3=true )
  #Do stuff with the args that returns a value
end

def test!(*p)
  replace test(*p)
end

--
Posted via http://www.ruby-forum.com/\.

That's an interesting way to do it. If I assume that any bang method I
write in a given class would also have a non-bang method, then I could
easily have a catch-all process define the methods for me when an
instance is generated. Cool!

···

--
Posted via http://www.ruby-forum.com/.

something like that?

#when something is called, call dup.something!

def method_missing(meth,*args)
  if respond_to?("#{meth}!")
    dup.send("#{meth}!",*args)
  else
    super
  end
end

#when something! is called, call replace something

def method_missing(meth,*args)
  if /(\w+)!/ =~ meth
    replace send($!,*args)
  else
    super
  end
end

PS: you cant use both at the same place :stuck_out_tongue:

···

--
Posted via http://www.ruby-forum.com/.

Hah, Ruby's always one step ahead of me :stuck_out_tongue:

···

--
Posted via http://www.ruby-forum.com/.

Edoardo Rossi wrote in post #1096893:

@Rossi `+1` to you.

···

On Thu, Feb 14, 2013 at 1:06 PM, Joel Pearson <lists@ruby-forum.com>

Hi...

IMHO sometimes this is useful:

def foo(something)
  dup.foo!(something)
end

def foo!(something)
  # do the work...
end

e.

--
Posted via http://www.ruby-forum.com/\.

Yup!
Hope this helps... happy hacking.
By the way... pay attention at all the consequences of 'dup'
See: Class: Object (Ruby 1.9.3)

e.

···

On Thu, Feb 14, 2013 at 1:49 PM, Joel Pearson <lists@ruby-forum.com> wrote:

That's an interesting way to do it. If I assume that any bang method I
write in a given class would also have a non-bang method, then I could
easily have a catch-all process define the methods for me when an
instance is generated. Cool!

--
Posted via http://www.ruby-forum.com/\.

There is one gotcha in this code: foo! will often return nil if
nothing is changed. A better approach is

def foo(something)
  dup.tap {|copy| copy.foo!(something)}
end

Kind regards

robert

···

On Thu, Feb 14, 2013 at 1:43 PM, Edoardo Rossi <edd.rossi@gmail.com> wrote:

IMHO sometimes this is useful:

def foo(something)
  dup.foo!(something)
end

def foo!(something)
  # do the work...
end

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/