Specify zero on the args command line

I have a command line tool that generates a flat json document. Imagine the following:

$ ruby gen-json.rb --foo bar --baz qux
{
    "foo": "bar"
    "baz": "qux"
}

I want this to work:

$ ruby gen-json.rb --foo $'\0' --baz qux
{
    "foo": null,
    "baz": "qux"
}

Instead of null, I get an empty string. To simplify this problem, consider this again:

$ cat nil-args.rb
puts "argv[0] is nil" if ARGV[0].nil?
puts "argv[0] is an empty string" if ARGV[0] == ""
puts "argv[1] is nil" if ARGV[1].nil?

I want to run it like this and get this output:

$ ruby nil-args.rb $'\0' foo
argv[0] is nil

But instead I get

argv[0] is an empty string

I suspect this is (possibly) a bug in the ruby ​​interpreter. It treats argv [0] as a C string whose zero terminates.

+3
source share
4 answers

Command line arguments are always strings. You will need to use a sentinel to indicate arguments that you want to handle differently.

+3
source

, , . , . script.

, , \0, , . .

, , , .

a = [1, 2, 3]
a[10].nil?
#=> true

, , :

$ ruby gen-json.rb --foo --baz qux
{
    "foo": null,
    "baz": "qux"
}

, , , , . .

script, , , (, , ):

require 'pp'

json = {}

ARGV.each_cons(2) do |key, value|
  next unless key.start_with? '--'
  json[key] = value.start_with?('--') ? nil : value
end

pp json

?:)

+1

Ruby , nil false true. ( 0 0.0).

nil - :

ARGV.map! do |arg|
  if arg.empty?
    nil
  else
    arg
  end
end

, nil.

0

, . "\0" ( , ). OptionParser:

require 'optparse'
require 'json'

values = {}
parser = OptionParser.new do |opts|
  opts.on("--foo VAL",:nulldetect) { |val| values[:foo] = val }
  opts.on("--bar VAL",:nulldetect) { |val| values[:foo] = val }

  opts.accept(:nulldetect) do |string|
    if string == '\0'
      nil
    else
      string
    end
  end
end

parser.parse!

puts values.to_json

, , , , , if "\0"

As an additional note, flags may be optional, but you get an empty string passed to the block, for example.

opts.on("--foo [VAL]") do |val|
  # if --foo is passed w/out args, val is empty string
end

So you still need a standalone

0
source

All Articles