on The Ruby Rogues podcast ✤ I was a Rubyist before Rails shipped and made us popular ✤ I have written a lot of code and documentation for Ruby, including the standard CSV library
childhood ✤ The female magic users have a strict training process built up over 100’s of years of magic use ✤ The male magic users, brand new to magic, try to catch up by using it for everything: cooking, chores, etc.
2' 42 $ ruby -e 'p "some data"' "some data" $ ruby -e 'var = 42; p var' 42 ✤ Run some Ruby without a script ✤ Hints: ✤ Use ‘…’ for shell quoting and “…” for Ruby quoting (to minimize escaping) ✤ Use ;’s to get multiple lines
2' 42 $ ruby -e 'p "some data"' "some data" $ ruby -e 'var = 42; p var' 42 ✤ Run some Ruby without a script ✤ Hints: ✤ Use ‘…’ for shell quoting and “…” for Ruby quoting (to minimize escaping) ✤ Use ;’s to get multiple lines
2' 42 $ ruby -e 'p "some data"' "some data" $ ruby -e 'var = 42; p var' 42 ✤ Run some Ruby without a script ✤ Hints: ✤ Use ‘…’ for shell quoting and “…” for Ruby quoting (to minimize escaping) ✤ Use ;’s to get multiple lines
2' 42 $ ruby -e 'p "some data"' "some data" $ ruby -e 'var = 42; p var' 42 ✤ Run some Ruby without a script ✤ Hints: ✤ Use ‘…’ for shell quoting and “…” for Ruby quoting (to minimize escaping) ✤ Use ;’s to get multiple lines
the command-line ✤ Or multiple names at once ✤ Or reads from STDIN ✤ Writes to STDOUT $ echo 'A line from file_1.' > file_1.txt $ echo 'A line from file_2.' > file_2.txt $ cat file_1.txt A line from file_1. $ cat file_1.txt file_2.txt A line from file_1. A line from file_2. $ echo 'A line from $stdin.' | cat A line from $stdin.
the command-line ✤ Or multiple names at once ✤ Or reads from STDIN ✤ Writes to STDOUT $ echo 'A line from file_1.' > file_1.txt $ echo 'A line from file_2.' > file_2.txt $ cat file_1.txt A line from file_1. $ cat file_1.txt file_2.txt A line from file_1. A line from file_2. $ echo 'A line from $stdin.' | cat A line from $stdin.
the command-line ✤ Or multiple names at once ✤ Or reads from STDIN ✤ Writes to STDOUT $ echo 'A line from file_1.' > file_1.txt $ echo 'A line from file_2.' > file_2.txt $ cat file_1.txt A line from file_1. $ cat file_1.txt file_2.txt A line from file_1. A line from file_2. $ echo 'A line from $stdin.' | cat A line from $stdin.
the command-line ✤ Or multiple names at once ✤ Or reads from STDIN ✤ Writes to STDOUT $ echo 'A line from file_1.' > file_1.txt $ echo 'A line from file_2.' > file_2.txt $ cat file_1.txt A line from file_1. $ cat file_1.txt file_2.txt A line from file_1. A line from file_2. $ echo 'A line from $stdin.' | cat A line from $stdin.
Unix Filter ✤ It supports the standard Unix Filter patterns ✤ You can use it like an IO object $ ruby -e 'puts ARGF.read' file_1.txt A line from file_1. $ ruby -e 'puts ARGF.read' file_1.txt file_2.txt A line from file_1. A line from file_2. $ echo 'A line from $stdin.' | ruby -e 'puts ARGF.read' A line from $stdin.
Unix Filter ✤ It supports the standard Unix Filter patterns ✤ You can use it like an IO object $ ruby -e 'puts ARGF.read' file_1.txt A line from file_1. $ ruby -e 'puts ARGF.read' file_1.txt file_2.txt A line from file_1. A line from file_2. $ echo 'A line from $stdin.' | ruby -e 'puts ARGF.read' A line from $stdin.
Unix Filter ✤ It supports the standard Unix Filter patterns ✤ You can use it like an IO object $ ruby -e 'puts ARGF.read' file_1.txt A line from file_1. $ ruby -e 'puts ARGF.read' file_1.txt file_2.txt A line from file_1. A line from file_2. $ echo 'A line from $stdin.' | ruby -e 'puts ARGF.read' A line from $stdin.
Unix Filter ✤ It supports the standard Unix Filter patterns ✤ You can use it like an IO object $ ruby -e 'puts ARGF.read' file_1.txt A line from file_1. $ ruby -e 'puts ARGF.read' file_1.txt file_2.txt A line from file_1. A line from file_2. $ echo 'A line from $stdin.' | ruby -e 'puts ARGF.read' A line from $stdin.
Unix Filter ✤ It supports the standard Unix Filter patterns ✤ You can use it like an IO object $ ruby -e 'puts ARGF.read' file_1.txt A line from file_1. $ ruby -e 'puts ARGF.read' file_1.txt file_2.txt A line from file_1. A line from file_2. $ echo 'A line from $stdin.' | ruby -e 'puts ARGF.read' A line from $stdin.
✤ Available everywhere ✤ It reads from ARGF ✤ You get a Unix Filter for free $ ruby -e 'puts gets' file_1.txt A line from file_1. $ ruby -e '2.times do puts gets end' file_1.txt file_2.txt A line from file_1. A line from file_2. $ echo 'A line from $stdin.' | ruby -e 'puts gets' A line from $stdin.
✤ Available everywhere ✤ It reads from ARGF ✤ You get a Unix Filter for free $ ruby -e 'puts gets' file_1.txt A line from file_1. $ ruby -e '2.times do puts gets end' file_1.txt file_2.txt A line from file_1. A line from file_2. $ echo 'A line from $stdin.' | ruby -e 'puts gets' A line from $stdin.
variable for “the current line:” $_ ✤ Note how it looks like a line ✤ Kernel#gets assigns to $_ ✤ Kernel#print prints $_ if no arguments are given $ ruby -e 'gets; print' file_1.txt A line from file_1. $ ruby -e 'gets; $_.tr! " ", "+"; print' file_1.txt A+line+from+file_1.
variable for “the current line:” $_ ✤ Note how it looks like a line ✤ Kernel#gets assigns to $_ ✤ Kernel#print prints $_ if no arguments are given $ ruby -e 'gets; print' file_1.txt A line from file_1. $ ruby -e 'gets; $_.tr! " ", "+"; print' file_1.txt A+line+from+file_1.
variable for “the current line:” $_ ✤ Note how it looks like a line ✤ Kernel#gets assigns to $_ ✤ Kernel#print prints $_ if no arguments are given $ ruby -e 'gets; print' file_1.txt A line from file_1. $ ruby -e 'gets; $_.tr! " ", "+"; print' file_1.txt A+line+from+file_1.
variable for “the current line:” $_ ✤ Note how it looks like a line ✤ Kernel#gets assigns to $_ ✤ Kernel#print prints $_ if no arguments are given $ ruby -e 'gets; print' file_1.txt A line from file_1. $ ruby -e 'gets; $_.tr! " ", "+"; print' file_1.txt A+line+from+file_1.
in a loop that: ✤ reads a line ✤ runs the -e code ✤ prints the line while gets # -e code goes here print end $ ruby -pe '# do nothing' file_1.txt file_2.txt A line from file_1. A line from file_2. $ ruby -pe '$_ = "Line #{ARGF.lineno}\n"' file_1.txt file_2.txt Line 1 Line 2
in a loop that: ✤ reads a line ✤ runs the -e code ✤ prints the line while gets # -e code goes here print end $ ruby -pe '# do nothing' file_1.txt file_2.txt A line from file_1. A line from file_2. $ ruby -pe '$_ = "Line #{ARGF.lineno}\n"' file_1.txt file_2.txt Line 1 Line 2
in a loop that: ✤ reads a line ✤ runs the -e code ✤ prints the line while gets # -e code goes here print end $ ruby -pe '# do nothing' file_1.txt file_2.txt A line from file_1. A line from file_2. $ ruby -pe '$_ = "Line #{ARGF.lineno}\n"' file_1.txt file_2.txt Line 1 Line 2
in a loop that: ✤ reads a line ✤ runs the -e code ✤ prints the line while gets # -e code goes here print end $ ruby -pe '# do nothing' file_1.txt file_2.txt A line from file_1. A line from file_2. $ ruby -pe '$_ = "Line #{ARGF.lineno}\n"' file_1.txt file_2.txt Line 1 Line 2
in a loop that: ✤ reads a line ✤ runs the -e code ✤ prints the line while gets # -e code goes here print end $ ruby -pe '# do nothing' file_1.txt file_2.txt A line from file_1. A line from file_2. $ ruby -pe '$_ = "Line #{ARGF.lineno}\n"' file_1.txt file_2.txt Line 1 Line 2
Range of two Regexp objects ✤ It “turns on” when the first matches and will stay true until the second matches $ ruby -e 'puts %w[one two three four five six]' > numbers.txt $ ruby -ne 'print if /\A[os]/../ee\Z/' numbers.txt one two three six
Range of two Regexp objects ✤ It “turns on” when the first matches and will stay true until the second matches $ ruby -e 'puts %w[one two three four five six]' > numbers.txt $ ruby -ne 'print if /\A[os]/../ee\Z/' numbers.txt one two three six
causes your filter to replace the input itself ✤ This is done with a buffer, so it feels like you are reading from and writing to the same place $ cat numbers.txt one two three four five six $ ruby -pi \ > -e '$_.tr! "aeiou", "X"' \ > numbers.txt $ cat numbers.txt XnX twX thrXX fXXr fXvX sXx
causes your filter to replace the input itself ✤ This is done with a buffer, so it feels like you are reading from and writing to the same place $ cat numbers.txt one two three four five six $ ruby -pi \ > -e '$_.tr! "aeiou", "X"' \ > numbers.txt $ cat numbers.txt XnX twX thrXX fXXr fXvX sXx
causes your filter to replace the input itself ✤ This is done with a buffer, so it feels like you are reading from and writing to the same place $ cat numbers.txt one two three four five six $ ruby -pi \ > -e '$_.tr! "aeiou", "X"' \ > numbers.txt $ cat numbers.txt XnX twX thrXX fXXr fXvX sXx
argument ✤ The original content is moved into a file with the backup suffix appended ✤ This can really protect you when you try to make sweeping changes with some gnarly Regexp! $ ruby -pi.bak \ > -e '$_.delete! "X"' \ > numbers.txt $ cat numbers.txt n tw thr fr fv sx $ cat numbers.txt.bak XnX twX thrXX fXXr fXvX sXx
argument ✤ The original content is moved into a file with the backup suffix appended ✤ This can really protect you when you try to make sweeping changes with some gnarly Regexp! $ ruby -pi.bak \ > -e '$_.delete! "X"' \ > numbers.txt $ cat numbers.txt n tw thr fr fv sx $ cat numbers.txt.bak XnX twX thrXX fXXr fXvX sXx
argument ✤ The original content is moved into a file with the backup suffix appended ✤ This can really protect you when you try to make sweeping changes with some gnarly Regexp! $ ruby -pi.bak \ > -e '$_.delete! "X"' \ > numbers.txt $ cat numbers.txt n tw thr fr fv sx $ cat numbers.txt.bak XnX twX thrXX fXXr fXvX sXx
argument ✤ The original content is moved into a file with the backup suffix appended ✤ This can really protect you when you try to make sweeping changes with some gnarly Regexp! $ ruby -pi.bak \ > -e '$_.delete! "X"' \ > numbers.txt $ cat numbers.txt n tw thr fr fv sx $ cat numbers.txt.bak XnX twX thrXX fXXr fXvX sXx
will let you change the split() pattern ✤ WARNING: this is a weird old switch that doesn’t allow a space before the pattern starts! $ echo "1,2, 3" | \ > ruby -naF',\s*' -e 'p $F' ["1", "2", "3\n"]
will let you change the split() pattern ✤ WARNING: this is a weird old switch that doesn’t allow a space before the pattern starts! $ echo "1,2, 3" | \ > ruby -naF',\s*' -e 'p $F' ["1", "2", "3\n"]
will let you change the split() pattern ✤ WARNING: this is a weird old switch that doesn’t allow a space before the pattern starts! $ echo "1,2, 3" | \ > ruby -naF',\s*' -e 'p $F' ["1", "2", "3\n"]
ending off of read input ✤ The record separator (Ruby’s idea of a line ending) can be changed by passing an octal character code to -0 (not shown) $ echo "1,2, 3" | \ > ruby -nalF',\s*' -e 'p $F' ["1", "2", "3"]
ending off of read input ✤ The record separator (Ruby’s idea of a line ending) can be changed by passing an octal character code to -0 (not shown) $ echo "1,2, 3" | \ > ruby -nalF',\s*' -e 'p $F' ["1", "2", "3"]
pill and pretend Ruby is always beautiful, without any of these ugly features ✤ You could take the red pill, go further down the rabbit hole, and learn yourself some command-line Ruby wizardry
the best ways to do things ✤ There are definitely shell commands that do some of these things better ✤ You can move on to learning those later ✤ Or you may already know them! ✤ That’s not the point ✤ The point: get new ideas and learn new things