在没有if ... else块的情况下处理Ruby中的命令行开关 [英] Handle command-line switch in Ruby without if...else block

查看:118
本文介绍了在没有if ... else块的情况下处理Ruby中的命令行开关的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在关于无条件编程的博文中,Michael Feathers显示如何限制如果语句可以用作降低代码复杂性的工具。

In a blog post about unconditional programming Michael Feathers shows how limiting if statements can be used as a tool for reducing code complexity.

他使用一个特定的例子来说明了他的观点。现在,我一直在考虑其他具体示例,可以帮助我了解更多关于无条件/ 如果更少/ 少编程。

He uses a specific example to illustrate his point. Now, I've been thinking about other specific examples that could help me learn more about unconditional/ifless/forless programming.

例如,使用 OptionParser 我制作了一个 cat 如果设置了 - upcase 开关,将克隆流的克隆:

For example, using OptionParser I made a cat clone that will upcase the stream if the --upcase switch is set:

#!/usr/bin/env ruby

require 'optparse'

options = {}
OptionParser.new do |opts|
  opts.banner = "Usage: cat [options] [file ...]"

  opts.on("-u", "--upcase", "Upcase stream") do
    options[:upcase] = true
  end
end.parse!

if options[:upcase]
  puts ARGF.read.upcase
else
  puts ARGF.read
end

如果没有 if..else 块,我将如何处理该交换机?

How would I handle that switch without an if..else block?

也对其他说明性具体例子的链接感兴趣。

Also interested in links to other illustrative specific examples.

推荐答案

试试这个,

#!/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.

有什么变化?


  • 该选项在内部重命名为:transform

  • 内部默认值为:本身

  • 命令行开关将内部选项设置为:upcase

  • 使用调用方法发送

  • 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

  • 可枚举#select

  • 可枚举#chunk

  • Enumerable#drop_while

  • Enumerable#slice_when

  • 可枚举#take_while

  • 等......

  • max
  • min
  • Hash#fetch
  • Enumerable#detect
  • Enumerable#select
  • Enumerable#chunk
  • Enumerable#drop_while
  • Enumerable#slice_when
  • Enumerable#take_while
  • etc...

另一种相关做法是 少编程。

Another related practice is forless programming.

如果你希望练习无条件和 for 减少编程,最好查看处理数组和字符串的示例,并使用Ruby的可枚举模块中的许多功能方法。

If you want to practice unconditional and forless 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"

这篇关于在没有if ... else块的情况下处理Ruby中的命令行开关的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆