Try this,
#!/usr/bin/env ruby
require 'optparse'
options = { :transform => :itself }
OptionParser.new do |opts|
opts.banner = "Usage: cat [options] [file ...]"
opts.on("-u", "--upcase", "Upcase stream") do
options[:transform] = :upcase
end
# add more options for downcase, reverse, etc ...
end.parse!
puts ARGF.read.send(options[:transform])
This worked quite well, I am actually surprised how well that worked.
What has been changed?
- The option is internally renamed to
:transform
- The internal default value is
:itself
- The command line switch sets the internal option to
:upcase
- Call the method with
send
Not all if
statements can be improved upon like this though. I would guess the idea of unconditional programming is to prefer a combination of meaningful default values, as I did above, and intention revealing functions whenever it seems reasonable but not at all costs.
Here are some examples of intention revealing functions,
max
min
Hash#fetch
Enumerable#detect
Enumerable#select
Enumerable#chunk
Enumerable#drop_while
Enumerable#slice_when
Enumerable#take_while
- etc...
Another related practice is for
less programming.
If you want to practice unconditional and for
less programming best look for examples that process arrays and strings and make use of the many "functional" methods in Ruby's enumerable module.
Here is an example of string justification without for
and if
,
str = 'This is an example to be aligned to both margins'
words = str.split
width, remainder = (50 - words.map(&:length).inject(:+)).divmod(words.length - 1)
words.take(words.length - 1).each { |each| width.times { each << 32 }}
words.take(words.length - 1).shuffle.take(remainder).each { |each| each << 32 }
p words.join
# => "This is an example to be aligned to both margins"
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…