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

M

Michelle Pace

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
 
R

Ryan Davis

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?

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

Michelle Pace

Ryan said:
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?
 
S

Steve Wilhelm

Michelle said:
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.
 
R

Ryan Davis

=20
Thanks for your reply Ryan... I'm surprised! So... are you saying that=20=
the method calls
=20
opts.parse!(argv) and opts.parse(argv)
=20
effectively do the same thing?

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.
 
M

Michelle Pace

Sorry Ryan... I'm still not getting it :-(

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.
 
E

Ehsanul Hoque

=20
Sorry Ryan... I'm still not getting it :-(
=20
What is that exclamation mark doing? Could I substitute lets say a 'w'=20
for the exclamation mark?
=20
opts.send:)parse!=2C argv) =3D> opts.send:)parsew=2C argv)
opts.send:)parse=2C argv) =3D> opts.send:)parse=2C argv)
=20
If I can=2C then I understand it. There are in fact two different methods= =20
'parsew' and 'parse'. But if thats true... then in my orginal code=20
above=2C there wasn't a 'parse!' method defined.
=20
--=20
Posted via http://www.ruby-forum.com/.
=20

I think you've got it. Basically parse!=2C and I mean all of it including t=
he exclamation mark=2C is a method defined separately from parse. In your o=
ptions class=2C they might look like this:

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

The example implementation is just a common idiom in ruby where a method en=
ding in a "bang"=2C or exclamation point is a destructive method=2C alterin=
g the state of the object=2C whereas the non-bang version of the method act=
s on a duplicate object=2C so as to keep the actual object unaltered. There=
is nothing special about the bang in how it is processed in ruby=2C it's j=
ust taken as part of the method name. So yes=2C you can just replace it wit=
h "w" or something. The reason for the bang is just ruby convention. If you=
wanted=2C you could reverse the definitions=2C and it would work fine=2C b=
ut just be confusing (don't do that=2C go by convention).=20

Hope that's clear.

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

Robert Klemme

Sorry Ryan... I'm still not getting it :-(

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

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,072
Latest member
trafficcone

Latest Threads

Top