0

Say I have

str = "DISABLE_THINGY=true -p my_profile"

To get the value of DISABLE_THINGY (true) I can use

str.partition("DISABLE_THINGY=").last.split(' ').first

I do not want to do that.

There must be a library that parses all this for me.

Anybody know some better ways?

David West
  • 2,256
  • 6
  • 32
  • 62
  • Can you not simply use the ENV array?? eg. puts ENV['DISABLE_THINGY'] – grail Apr 27 '17 at 16:47
  • "There must be a library that parses all this for me." Possibly, but asking for us to find one for you is off-topic. Instead, you're supposed to do the research, find what sounds usable, test, decide on which works best for you, write code, and then, when you run into a specific problem, ask a specific question about it. Please read "[ask]". – the Tin Man Apr 27 '17 at 17:09
  • Possible duplicate of [Parse command line arguments in a Ruby script](http://stackoverflow.com/questions/26434923/parse-command-line-arguments-in-a-ruby-script) – David West Apr 27 '17 at 17:13

2 Answers2

2

The selected answer is way too convoluted to solve such a simple problem. Regular expressions are great, but the more complex they are, the more likely they'll be wrong:

str = "DISABLE_THINGY=true -p my_profile"
str[/\w+=(\w+)/, 1] # => "true"

/\w+=(\w+)/ simply looks for "words" joined by =.

See String's [] method for more information.

If you had a number of assignments and wanted to capture them all, or, wanted to capture the name and value of this one:

str = "DISABLE_THINGY=true -p my_profile"
str.scan(/\w+=\w+/).map { |s| s.split('=') } # => [["DISABLE_THINGY", "true"]]

That returns an array-of-arrays, which can be useful, or, you could convert that to a Hash:

str.scan(/\w+=\w+/).map { |s| s.split('=') }.to_h # => {"DISABLE_THINGY"=>"true"}

and similarly:

str = "DISABLE_THINGY=true FOO=bar -p my_profile"
str.scan(/\w+=\w+/).map { |s| s.split('=') } # => [["DISABLE_THINGY", "true"], ["FOO", "bar"]]
str.scan(/\w+=\w+/).map { |s| s.split('=') }.to_h # => {"DISABLE_THINGY"=>"true", "FOO"=>"bar"}
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
  • Yeah, I guess I went too far to answer the question "how do I simply get DISABLE_THINGY from my string provided". In saying that, my solution allows getting both ENV variables and CLI parameters (with hyphens and without equals signs), where yours is only getting ENV variables with equals signs. I guess adjusting your solution to support both as well might be relatively easy, but either way, I probably did assume he wanted everything and not exactly what he asked :). – Lance Whatley Apr 27 '17 at 17:25
  • ...or `"a=b 1 c=d 2".scan(/(\w+)=(\w+)/) #=> [["a", "b"], ["c", "d"]]`. – Cary Swoveland Apr 27 '17 at 18:43
  • Yes. This particular expression comes from part of how we used to parse a URL's parameters into a hash: `'a=1&b=2'.split('&').map { |s| s.split('=') }.to_h # => {"a"=>"1", "b"=>"2"}` – the Tin Man Apr 27 '17 at 19:15
1

Take a look at "Parse command line arguments in a Ruby script".

If all of your arguments don't use a hyphen, you might have to make slight tweaks to the regex used, but this should get you where you need to go. Just replace ARGV.join(' ') in the accepted answer with your str var.

Adjusted the regex in the link provided above to make your use-case work where you combine ENV variables with command line parameters:

args = Hash[ str.scan(/-{0,2}([^=\s]+)(?:[=\s](\S+))?/) ] => {"DISABLE_THINGY"=>"true", "p"=>"my_profile"}
Community
  • 1
  • 1
Lance Whatley
  • 2,395
  • 1
  • 13
  • 16
  • With the string str being "DISABLE_THINGY -p my_profile" `irb(main):021:0> args = Hash[ str.scan(/--?([^=\s]+)(?:=(\S+))?/) ] => {"p"=>nil}` No joy :( – David West Apr 27 '17 at 15:49
  • Yeah figured you'd have to adjust the regex. Try the following: `args = Hash[ str.scan(/-{0,2}([^=\s]+)(?:[=\s](\S+))?/) ] => {"DISABLE_THINGY"=>"true", "p"=>"my_profile"}` – Lance Whatley Apr 27 '17 at 16:00
  • Edited my response with the new regex and solution. Let me know if this isn't what you're looking for. – Lance Whatley Apr 27 '17 at 16:03