Escape $ for command line Ruby script - ruby

I have a Ruby script where I want to take money as a command line input like this:
>ruby myscript.rb Rob $100
where $100 is dollars.
However, $ is a special character in bash, which interprets the $100 as $1 and my Ruby script gets "00" as the command line input(ARGV), when I want the complete $100.
Is there a way to get the unescaped version of the dollar field? (I know that '$100' will retain the raw value, but the API I've been given means that the user can't be burdened with remembering to quote all dollar values)
Thanks in advance for any ideas here!

Can't you just use a bit different approach? Something like this:
puts "Provide your name:"
name = gets.chomp
puts "Hey, #{name}, how much are you ready to pay?"
money = gets.chomp
puts "#{name}, thanks for your #{money}"
from user's side it will look like:
# Provide your name:
# Rob
# Hey, Rob, how much are you ready to pay?
# $100
# Rob, thanks for your $100

Related

Ruby: Adding a Symbol to the input line in Terminal?

Is it possible to have a symbol, like a dollar sign $, appear before a the cursor on the user input line, in the terminal? Like a prompt, kind of.
For example. If you had something like:
puts "How much money do you want?"
gets.to_i
and would output in the terminal
How much money do you want?
$ >
Thanks!
Here's an easy way:
print "$ >"
input = gets.chop
Since I use print instead of puts it doesn't put a newline after that.
This is kinda rudimentary, and there are certainly more advanced ways to do this (e.g. with ncurses and other libraries)

Multibyte character issue with .match?

The following code is something I am beginning to test for use within a "Texas Hold Em" style game I am working on.
My question is why, when running the following code, does the puts involving a "♥" return a "\u" in it's place. I feel certain it is this multibyte character that is causing the issue becuse on the second puts , I replaced the ♦ with a d in the array of strings and it returned what i was expecting. See Below:
My Code:
#! /usr/bin/env ruby
# encoding: utf-8
table_cards = ["|2♥|", "|8♥|", "|6d|", "|6♣|", "|Q♠|"]
# Array of cards
player_1_face_1 = "8"
player_1_suit_1 = "♦"
# Player 1's face and suit of first card he has
player_1_face_2 = "6"
player_1_suit_2 = "♥"
# Player 1's face and suit of second card he has
test_str_1 = /(\D8\D{2})/.match(table_cards.to_s)
# EX: Searching for match between face values on (player 1's |8♦|) and the |8♥| on the table
test_str_2 = /(\D6\D{2})/.match(table_cards.to_s)
# EX: Searching for match between face values on (player 1's |6♥|) and the |6d| on the table
puts "#{test_str_1}"
puts "#{test_str_2}"
Puts to Screen:
|8\u
|6d|
-- My goal would be to get the first puts to return: |8♥|
I am not so much looking for a solution to this (there may not even be one) but more so a "as simple as possible" explanation of what is causing this issue and why. Thanks ahead of time for any information on what is happening here and how I can tackle the goal.
The "\u" you're seeing is the Unicode string indicator.
For example, Unicode character 'HEAVY BLACK HEART' (U+2764) can be printed as "\u2764".
A friendly Unicode character listing site is http://unicode-table.com/en/sets/
Are you able to launch interactive Ruby in your shell and print a heart like this?
irb
irb> puts "\u2764"
❤
When I run your code in my Ruby, I get the answer you expect:
test_str_1 = /(\D8\D{2})/.match(table_cards.to_s)
=> #<MatchData "|8♥|" 1:"|8♥|">
What happens if you try a regex that is more specific to your cards?
test_str_1 = /(\|8[♥♦♣♠]\|)/.match(table_cards.to_s)
In your example output, you're not seeing the Unicode heart symbol as you want. Instead, your output is printing the "\u" which is the Unicode starter, but then not printing the rest of the expected string which is "2764".
See the comment by the Tin Man that describes encoding for your console. If he's correct, then I expect the more-specific regex will succeed, but still print the wrong output.
See the comment by David Knipe that says it looks like it gets truncated because the regex only matches 4 characters. If he's correct, then I expect the more-specific regex will succeed and also print the right output.
(The rest of this answer is typical for Unix; if you're on Windows, ignore the rest here...)
To show your system language settings, try this in your shell:
echo $LC_ALL
echo $LC_CTYPE
If they are not "UTF-8" or something like that, try this in your shell:
export LC_ALL=en_US.UTF-8
export LC_CTYPE=en_US.UTF-8
Then re-run your code -- be sure to use the same shell.
If this works, and you want to make this permanent, one way is to add these here:
# /etc/environment
LC_ALL=en_US.UTF-8
LC_CTYPE=en_US.UTF-8
Then source that file from your .bashrc or .zshrc or whatever shell startup file you use.

How do I write shell-like scripts using Ruby?

I have a task of writing a simple Ruby script which would do the following.
Upon execution from the UNIX command line, it would present the user with a prompt at which he should be able to run certain commands, like "dir", "help" or "exit". Upon "exit" the user should return to the Unix shell.
I'm not asking for the solution; I would just like to know how this "shell" functionality can be implemented in Ruby. How do you present the user with a prompt and interpret commands.
I do not need a CLI script that takes arguments. I need something that creates a shell interface.
The type of program you require can easily be made with just a few simple constructs.
I know you're not asking for a solution, but I'll just give you a skeleton to start off and play around with:
#!/usr/bin/env ruby
def prnthelp
puts "Hello sir, what would you like to do?"
puts "1: dir"
puts "2: exit"
end
def loop
prnthelp
case gets.chomp.to_i
when 1 then puts "you chose dir!"
when 2 then puts "you chose exit!"
exit
end
loop
end
loop
Anyways, this is a simplistic example on how you could do it, but probably the book recommended in the comments is better. But this is just to get you off.
Some commands to get you started are:
somevar = gets
This gets user input. Maybe learn about some string methods to manipulate this input can do you some good. http://ruby-doc.org/core-2.0/String.html
chomp will chop off any whitespace, and to_i converts it to an integer.
Some commands to do Unix stuff:
system('ls -la') #=> outputs the output of that command
exit #=> exits the program
Anyways, if you want this kind of stuff, I think it's not a bad idea to look into http://www.codecademy.com/ basically they teach you Ruby by writing small scripts such as these. However, they maybe not be completely adapted to Unix commands, but user input and the likes are certainly handled.
Edit:
As pointed out do use this at the top of your script:
#!/usr/bin/env ruby
Edit:
Example of chomp vs. chop:
full_name = "My Name is Ravikanth\r\n"
full_name.chop! # => "My Name is Ravikanth"
Now if you run chop and there are no newline characters:
puts full_name #=> "My Name is Ravikanth"
full_name.chop! #=> "My Name is Ravikant"
versus:
puts full_name #=> "My Name is Ravikanth\r\n"
full_name.chomp! #=> "My Name is Ravikanth"
full_name.chomp! #=> "My Name is Ravikanth"
See: "Ruby Chop vs Chomp"
Here's a really basic loop:
#!/user/bin/ruby
#
while true do
print "$ "
$stdout.flush
inputs = gets.strip
puts "got your input: #{inputs}"
# Check for termination, like if they type in 'exit' or whatever...
# Run "system" on inputs like 'dir' or whatever...
end
As Stefan mentioned in a comment, this is a huge topic and there are scenarios that will make this complicated. This is, as I say, a very basic example.
Adding to the two other (valid) answers posted so far be wary of using #!/usr/bin/ruby, because ruby isn't always installed there. You can use this instead:
#!/usr/bin/env ruby
Or if you want warnings:
#!/usr/bin/env ruby -w
That way, your script will work irrespective of differences where ruby might be installed on your server and your laptop.
Edit: also, be sure to look into Thor and Rake.
http://whatisthor.com
http://rake.rubyforge.org
Use irb.
I was looking into an alternative to bash and was thinking along the same lines... but ended up choosing fish: http://fishshell.com/
Nonetheless, I was thinking of using irb and going along the lines of irbtools: https://github.com/janlelis/irbtools
Example:
> irb
Welcome to IRB. You are using ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-linux]. Have fun ;)
>> ls #=> ["bin", "share", "opt", "lib", "var", "etc", "src"]
>>
In any case, irb is the ruby shell.
Take a look at cliqr which comes with inbuilt support for build a custom shell https://github.com/anshulverma/cliqr/

Ruby: syntax for string interpolation and commenting

There are a lot of similar questions to this one but i think none really had the answer i was in need of.
From what i perceived, anything that has a # preceding it becomes a comment, as in:
puts "not a comment"
# puts "in a comment"
but when it come to string interpolation, you can say:
puts "time is #{Time.now}"
and the # at #{Time.now} doesn't start commenting whatever is written after it.
How is it so?
The # sign in this case is encased in quotation marks, and is parsed as part of the string, not as a comment.
Yes, what #Osama said. But also, if you put a comment inside the chunk of Ruby code, it won't comment out the rest of the entire line. So,
puts "'#{'oof'#.reverse},' he said."
wil print "'oof,' he said", while
puts "'#{'oof'.reverse},' he said."
results in "'foo,' he said".

How to add extra newline with 'puts' without sticking newline character into string?

If I say
puts "Hello"
and decide to add an extra newline I need to do this:
puts "Hello\n"
Having this character in the string is ugly. Is there any way to do this without polluting my string?
Just make another call to puts:
puts "Hello"
puts
puts "Hello",""
I often find myself adding a constant in ruby to contain these characters
NEW_LINE = "\n"
puts "Hello" + NEW_LINE
I think it is more readable and makes a change to all newline characters easy if anyone ever decides to separate each line by something else at some later date.
Do you think this looks nicer?
puts "Hello"+$/
</evil>
The reason Ruby uses "\n" for a newline is because its based on C. Ruby MRI is written in C and even JRuby is written in Java which is based on C++ which is based on C... you get the idea! So all these C-style languages use the "\n" for the new line.
You can always write your own method that acts like puts but adds new lines based upon a parameter to the method.
you can just write
p "Hello"
p
That should work as well if you want to keep it short and simple
Well, I don't think an explicit newline is ugly. mipadi's answer is just fine as well. Just to throw another answer in, make an array of the lines then join the aray with a newline. :)
What you want fixed:
input for script:
puts "Hello there"
puts "Goodbye"
Output from script:
Hello thereGoodbye
Fix for the problem:
Input for script:
puts "Hello there"
puts
puts "Goodbye"
Output from script:
Hello there
Goodbye

Resources