Best way to deal with command line options

Hi,

I’m verry new to ruby, just use it for some days now and I have question
about the best implementation of how to deal with command line options.

Suppose I have a program, with a class say A and a main.
My program also has a verbose option (program --verbose).
What’s the best way to implement the verbose option in a OO-way?

a) give the boolean verbose to the class and let the class control it.
(method(verbose) --> puts “something” if verbose)
b) run the program and let the main handle with the verbose option.
c) something else

A second question about this is suppose my program runs a loop for a
number of times and the user may specify the number of loops to make,
and if the program must run to the end in once or ask for user action
every x steps)
like: program --loops 50 --steps 5 --> this would ask for user input
every 5yt steps and loops 50 times.

What’s the best way to do this?

a) again let the class handle it (a method run(number_of_loops, steps))
b) or let the main handle it (in the class just a method step() and in
the main the method run(number_of_loops, steps))
c) something else

I hope you understand my problem

Thanks,
Thomas

On Jun 19, 2006, at 13:14, thomas coopman wrote:

Suppose I have a program, with a class say A and a main.
My program also has a verbose option (program --verbose).
What’s the best way to implement the verbose option in a OO-way?

a) give the boolean verbose to the class and let the class control
it. (method(verbose) --> puts “something” if verbose)
b) run the program and let the main handle with the verbose option.
c) something else

Hard to say without a little more knowledge of the program and the
nature of the class. In general I’d say it depends mostly on how
many different places in the code would have different behaviour
based on the parameter. In other words, how many places in the code
need something like this: “if @verbose then…”

If there’s just one place, then it’s fine to do it there.

If there’s more than one place, then you want to make it one place.
One way of doing this is using a logger: the class would always
tell the logger what’s going on, and the logger worries about the
verbose parameter and whether or not to tell you. Sort of like this:

class A
def initialize(verbose = false)
@logger = Logger.new(verbose)
end
def do_something_complicated
@logger.write(“verbose information”)
end
def do_something_even_more_complicated
@logger.write(“verbose information”)
@logger.write(“more verbose information”)
end
end

class Logger
def initialize(verbose = false)
@verbose = verbose
end
def write(str)
puts str if @verbose
end
end

The Logger class in Ruby’s stdlib does exactly this, but in a
significantly more sophisticated way.

steps))
b) or let the main handle it (in the class just a method step() and
in the main the method run(number_of_loops, steps))
c) something else

a) and b) are the same thing, it’s just the location of the ‘run’
method that’s different, so the question boils down to “where’s the
appropraite place to have my ‘run’ method?” Which is actually quite
difficult to answer without knowing anything about the code. Do you
think that the ‘run’ method is integral to the A class? Or is it
more of a user-interface thing that should be separate from A? Both
approaches could be justified.

matthew smillie.

On Mon, 19 Jun 2006 22:50:09 +0900
Matthew S. [email protected] wrote:

If there’s more than one place, then you want to make it one place.
One way of doing this is using a logger: the class would always
tell the logger what’s going on, and the logger worries about the
verbose parameter and whether or not to tell you. Sort of like this:

The Logger class in Ruby’s stdlib does exactly this, but in a
significantly more sophisticated way.

That’s a good idea, I will look into that or else write my own simple
logger class

It’s indeed a question about where to put the run method, it should
probably be placed in the class itself and not in the main.

Another little question, what’s the best way to do when writing a
program in ruby,
keep the core and the main in different files, place them in the same
file,… or doesn’t it matter?

Thanks,

Thomas Coopman

On Tue, 20 Jun 2006 00:45:00 +0900
Matthew S. [email protected] wrote:

end
the same file can lead to problems if you ever want to use your

Thanks for your answers!

Thomas Coopman

Another little question, what’s the best way to do when writing a
program in ruby,
keep the core and the main in different files, place them in the
same file,… or doesn’t it matter?

To be honest, I’m not 100% sure what you mean by ‘main’. I’m
guessing it’s something like this:

Class A

end
Class B

end

‘main’ starts here.

a = A.new

In one sense it doesn’t matter. But including things like that in
the same file can lead to problems if you ever want to use your
classes in a different file - your ‘main’ will get executed when you
‘require’ the original file. It’s likely best in the long run to
separate specific programs using your classes from the classes
themselves. If you feel like cheating, though, you can always do this:

if $0 == FILE

main goes in here

end

matthew smillie

thomas coopman wrote:

Hi,

I’m verry new to ruby, just use it for some days now and I have question about the best implementation of how to deal with command line options.

Suppose I have a program, with a class say A and a main.
My program also has a verbose option (program --verbose).
What’s the best way to implement the verbose option in a OO-way?

These kind of options are often best implemented via global vars. eg.
$VERBOSE. That might seems anti OOP but the reason is that if your
program gets big --ie. spreads across multiple classes, passing such
“universally applicable” options around gets old real qucik.

T.

On 6/19/06, thomas coopman [email protected] wrote:

Another little question, what’s the best way to do when writing a program
in ruby,
keep the core and the main in different files, place them in the same
file,… or doesn’t it matter?

SOC - Separation of Concerns. At least keep them in separate classes. If
the
work class is sharable, put it in a separate file or library.

Example:

require ‘rubygems’
require ‘commandline’

class App < CommandLine::Application
def initialize
author “Me, Myself”
synopsis “[-dhv] file1 file2”
short_description “…”
expected_args :file1, :file2
end

def main
MyWorkClass.new(args, opts)
end
end

class MyWorkClass
def initialize

this class does all the work.
The command line app is just interface with the user
end
end

Thanks,

Thomas Coopman

Jim