Meaning of '!(...' EG: "myObject.parse!(argv)" ..?

Hi there,

QUESTION:
Whilst "parse(argv)" is obvious, what does "opts.parse!(argv)" do in the
below code? And what is the word use to describe doing this?

CONTEXT:
I am looking at a class called 'Options' whose job is to parse command
line options which get passed to a program called 'PartInspector'. An
extract of this class follows:

···

------------------------------------------------------------
class Options

  def initialize(argv)
    @directory = DEFAULT_DIR
    parse(argv)
  end

  private
    def parse(argv)
      OptionParser.new do |opts|
      opts.banner = "Usage: PartInspector [part_number]"

      opts.on("-h", "Shows this message") do
        puts opts
        exit
      end

      begin
        argv = ["-h"] if argv.empty?
        opts.parse!(argv) ## <------- HERE?!!?!
        rescue OptionParser::ParseError => e
          STDERR.puts e.message, "\n", opts
      end
    end#def parse()
   end#private class

end#option class
------------------------------------------------------------

I know its probably some basic syntax for ruby, not knowing what it is
called however makes it difficult to look it up.

Thank-you in advance, Michelle
--
Posted via http://www.ruby-forum.com/.

it is just an argument list. nothing fancy. "!" is valid as part of the method name, that's all.

···

On Nov 16, 2009, at 22:15 , Michelle Pace wrote:

QUESTION:
Whilst "parse(argv)" is obvious, what does "opts.parse!(argv)" do in the
below code? And what is the word use to describe doing this?

Ryan Davis wrote:

it is just an argument list. nothing fancy. "!" is valid as part of the
method name, that's all.

Thanks for your reply Ryan... I'm surprised! So... are you saying that
the method calls

         opts.parse!(argv) and opts.parse(argv)

effectively do the same thing?

···

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

Michelle Pace wrote:

Thanks for your reply Ryan... I'm surprised! So... are you saying that
the method calls

         opts.parse!(argv) and opts.parse(argv)

effectively do the same thing?

Section 6.2 of "The Ruby Programming Language" by Flanagan & Matsumoto,
explains that a method that ends with an exclamation mark is a naming
convention indicating to the programmer that the method "should be used
with caution."

It goes on to explain that most of the time this is due to the fact that
the method is a mutator; a method that alters the internal state of the
object.

···

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

Are they both plain happy method calls? Yes. If by "do the same thing" you mean call the same method, then no.

They are both equivalent to:

  opts.send(:parse!, argv)

and

  opts.send(:parse, argv)

respectively.

···

On Nov 16, 2009, at 23:04 , Michelle Pace wrote:

Ryan Davis wrote:

it is just an argument list. nothing fancy. "!" is valid as part of the
method name, that's all.

Thanks for your reply Ryan... I'm surprised! So... are you saying that
the method calls

        opts.parse!(argv) and opts.parse(argv)

effectively do the same thing?

Sorry Ryan... I'm still not getting it :frowning:

What is that exclamation mark doing? Could I substitute lets say a 'w'
for the exclamation mark?

opts.send(:parse!, argv) => opts.send(:parsew, argv)
opts.send(:parse, argv) => opts.send(:parse, argv)

If I can, then I understand it. There are in fact two different methods
'parsew' and 'parse'. But if thats true... then in my orginal code
above, there wasn't a 'parse!' method defined.

···

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

Sorry Ryan... I'm still not getting it :frowning:

What is that exclamation mark doing? Could I substitute lets say a 'w'
for the exclamation mark?

opts.send(:parse!, argv) => opts.send(:parsew, argv)
opts.send(:parse, argv) => opts.send(:parse, argv)

If I can, then I understand it. There are in fact two different methods
'parsew' and 'parse'. But if thats true... then in my orginal code
above, there wasn't a 'parse!' method defined.

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

I think you've got it. Basically parse!, and I mean all of it including the exclamation mark, is a method defined separately from parse. In your options class, they might look like this:

class Options
def parse!(argv)
# parsing code
end
def parse(argv)
opts = self.dup
opts.parse!(argv)
end
end

The example implementation is just a common idiom in ruby where a method ending in a "bang", or exclamation point is a destructive method, altering the state of the object, whereas the non-bang version of the method acts on a duplicate object, so as to keep the actual object unaltered. There is nothing special about the bang in how it is processed in ruby, it's just taken as part of the method name. So yes, you can just replace it with "w" or something. The reason for the bang is just ruby convention. If you wanted, you could reverse the definitions, and it would work fine, but just be confusing (don't do that, go by convention).

Hope that's clear.

- Ehsan

···

_________________________________________________________________
Windows 7: It works the way you want. Learn more.
http://www.microsoft.com/Windows/windows-7/default.aspx?ocid=PID24727::T:WLMTAGL:ON:WL:en-US:WWL_WIN_evergreen:112009v2

Yes. The exclamation mark is just more visible than the "w". In the particular case of OptionParser the difference between #parse and #parse! is that the latter actually modifies the argument (typically ARGV), which btw. is a nice thing because what it leaves behind in ARGV are only file names and so using ARGF works well together with OptionParser. I typically do

OptionParser.new do |opts|
   opts.on ...
end.parse! ARGV

Then, depending on what the program does

ARGF.each do |line|
   puts "read a line: #{line}"
end

Kind regards

  robert

···

On 17.11.2009 09:48, Michelle Pace wrote:

Sorry Ryan... I'm still not getting it :frowning:

What is that exclamation mark doing? Could I substitute lets say a 'w' for the exclamation mark?

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

Ja, great! Thanks Ehsan - I've got it now :slight_smile:

Michelle

···

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