Rake从参数中删除尾随空格。如何预防?

时间:2017-08-10 20:11:48

标签: ruby-on-rails ruby command-line rake rake-task

有一个简单的rake任务:

task :ws, [:str] => :environment do |t, args|
  puts args.str.inspect
end

在命令行中运行此任务时,我得到以下结果:

$ rake ws[' ']
nil

$ rake ws['    ']
nil

$ rake ws['    1']
"    1"

$ rake ws['    1    ']
"    1"

$ rake 'ws[ ]'
nil

$ rake 'ws[    ]'
nil

$ rake 'ws[    1]'
"    1"

$ rake 'ws[    1    ]'
"    1"

当在rails控制台中调用任务时,一切都按预期工作:

2.3.3 :258 > Rake::Task['ws'].invoke(' ')
" "
2.3.3 :259 > Rake::Task['ws'].reenable
2.3.3 :260 > Rake::Task['ws'].invoke('    ')
"    "
2.3.3 :261 > Rake::Task['ws'].reenable
2.3.3 :262 > Rake::Task['ws'].invoke('    1')
"    1"
2.3.3 :263 > Rake::Task['ws'].reenable
2.3.3 :264 > Rake::Task['ws'].invoke('    1    ')
"    1    "

同样,绝对不是操作系统负责修剪,因为它不应该在引号之间修剪任何东西。此外,它可以通过这种方式轻松测试:

task :ws, [:str] => :environment do |t, args|
  puts args.str.inspect
  puts ARGV[1].inspect
end

然后在命令行中:

$ rake 'ws[  1  ]' '  2  '
"  1"
"  2  "

在命令行中运行任务时,是否可以以某种方式保留尾随空格?不使用命令行参数(上例中的' 2 '),因为Rake将尝试为每个此类参数执行任务,并且如果找不到任务将引发错误,或者如果找到任务则会更糟,然后它将执行它。

Rake版本12.0.0

1 个答案:

答案 0 :(得分:1)

您可以在空白的末尾转义单个空格字符,如下所示:

rake 'ws[   2  \ ]'
"   2   "

这似乎与你想要的一样。

反斜杠作为参数的一部分传递,反斜杠空间对被解释为另一层中的空格(通过设计或意外?)。

看看Rake::Application#parse_task_string。你可以用irb来实验自己,例如

Rake::Application.new.parse_task_string('ws[   1   ]')
=> ["ws", ["   1"]]

Rake::Application.new.parse_task_string('ws[   1  \ ]')
=> ["ws", ["   1   "]] 

我实际上想要逐步了解这是怎么回事。

首先,它会像你这样分割你的任务名称和参数:

/^([^\[]+)(?:\[(.*)\])$/ =~ 'ws[    1    ]'

现在我们"ws"中的$1" 1 "中的$2。到目前为止都很好。 $2变为remaining_argsremaining_args然后被另一个正则表达式重复传递而被切断:

/((?:[^\\,]|\\.)*?)\s*(?:,\s*(.*))?$/ =~ remaining_args # Starts as "    1    "

现在$1" 1"\s*在任何一个参数的末尾都在吃任何连续的空格。

那么为什么退格会保留这些空格呢?

  1. 允许单个空格字符在退格后生存(由捕获组中的\\.捕获)。此外,还会捕获退格所有内容。

  2. 然后将参数字符串传递给.gsub(/\\(.)/, '\1')。这会将backspace-anything替换为anything。因此,退格空间对用空格替换。 我想知道为什么他们不只是.gsub(/\\/, '')必须允许转义反斜杠。

  3. 当前实现还将保留一个退格,该退格恰好是参数结尾处的最后一个char,无论出于何种原因。作为副作用,似乎用反斜杠(即使是反转的反斜杠)结束单个参数会将整个参数转换为空字符串,例如

    Rake::Application.new.parse_task_string('task[tears in rain\]')
    =>["task", [""]]
    

    这很有趣(例如,如果您需要传递Windows目录)。

    Rake::Application.new.parse_task_string('task[C:\\Johnny\\Likes\\Windows\\]')
    =>["task", [""]]
    

    猜测作者的意图是允许你转义逗号以避免拆分参数字符串。它具有允许您传递空白的副作用。我不会依赖它......