rexe 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/README.md +232 -363
  4. data/exe/rexe +18 -14
  5. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ad9ebb60746e9796db2a6f284cf0d0aee226db27e665710cdfc18714ec0e6363
4
- data.tar.gz: f2cbb93e42bca15ffab3d9b240785427c70a6ed507b33c9673eb9536d0a0a343
3
+ metadata.gz: 3da97ba4789e0253cb504694362282b40e5e06c153eda6c1b3c74e0a1836e5b7
4
+ data.tar.gz: a3d8ee332bd23f6b77c4a01ee1a0f011aab5131c7aca42ec79984d1e3b1ee55b
5
5
  SHA512:
6
- metadata.gz: 17a9cf1e2ece63be47427236a3803ff2ddd7bf144774755c567e7074ad43c6aff19799a2e3651bc8a81fcc7a7550eae3968e9525942f4d4bccb4127e0c481fe4
7
- data.tar.gz: 484af00828303109e4b9904316700f25340cee8314e0a4e038b5166b2b5410c8e5731b0b6bb6ab91414b03c1bf709d532048d2cf975fcffac782d47db07c0209
6
+ metadata.gz: de3d6ffc907b7ef0fe448970671e6d6399a5f6eb86fecc88c805a88f1ae13ad7f71aad3339fddafce449711c9952319879894149651e6aeb5c021ba3b74a6d3a
7
+ data.tar.gz: 54e8c67c50a4e48dc612f170851462921ceab006d8788e8133a769c4abbd24a0adaace90453a594daaae5b3e3cb22b53577d19750fa37baefcbd6e7ba9ded71e
data/CHANGELOG.md CHANGED
@@ -1,6 +1,12 @@
1
1
  ## rexe -- Ruby Command Line Executor/Filter
2
2
 
3
3
 
4
+ ### 1.0.1
5
+
6
+ * Improve help text.
7
+ * Improve code block display in readme.
8
+
9
+
4
10
  ### 1.0.0
5
11
 
6
12
  * Suppress help message on SystemExit.
data/README.md CHANGED
@@ -10,29 +10,24 @@ __Rexe__ is a Ruby script and gem that multiplies Ruby's usefulness and concisen
10
10
 
11
11
  ----
12
12
 
13
- Shell scripting is great for simple tasks but for anything nontrivial
14
- it can easily get cryptic and awkward (pun intended!).
13
+ Shell scripting is great for simple tasks but for anything nontrivial it can easily get cryptic and awkward (pun intended!).
15
14
 
16
- This problem can often be solved by writing a Ruby script instead. Ruby provides fine
17
- grained control in a language that is all about clarity, conciseness, and expressiveness.
15
+ This problem can often be solved by writing a Ruby script instead. Ruby provides fine grained control in a language that is all about clarity, conciseness, and expressiveness.
18
16
 
19
- Unfortunately, when there are multiple OS commands to be called, then Ruby can be
20
- awkward too.
17
+ Unfortunately, when there are multiple OS commands to be called, then Ruby can be awkward too.
21
18
 
22
- Sometimes a good solution is to combine Ruby and shell scripting on the same
23
- command line. Rexe multiplies your power to do so.
19
+ Sometimes a good solution is to combine Ruby and shell scripting on the same command line. Rexe multiplies your power to do so.
24
20
 
25
21
 
26
22
  ### Using the Ruby Interpreter on the Command Line
27
23
 
28
- Let's start by seeing what the Ruby interpreter already provides.
29
- Here we use `ruby` on the command line, using an intermediate environment variable to
30
- simplify the logic and save the data for use by future commands.
31
- An excerpt of the output follows the code:
24
+ Let's start by seeing what the Ruby interpreter already provides. Here we use `ruby` on the command line, using an intermediate environment variable to simplify the logic and save the data for use by future commands. An excerpt of the output follows the code:
32
25
 
33
- ```
26
+ ```bash
34
27
  ➜ ~  export EUR_RATES_JSON=`curl https://api.exchangeratesapi.io/latest`
35
28
  ➜ ~  echo $EUR_RATES_JSON | ruby -r json -r yaml -e 'puts JSON.parse(STDIN.read).to_yaml'
29
+ ```
30
+ ```yaml
36
31
  ---
37
32
  rates:
38
33
  MXN: 21.96
@@ -43,23 +38,19 @@ base: EUR
43
38
  date: '2019-03-08'
44
39
  ```
45
40
 
46
- Unfortunately, the configuration setup (the `require`s) along with the reading, parsing, and formatting
47
- make the command long and tedious, discouraging this approach.
41
+ Unfortunately, the configuration setup (the `require`s) along with the reading, parsing, and formatting make the command long and tedious, discouraging this approach.
48
42
 
49
43
  ### Rexe
50
44
 
51
- Rexe [see footnote ^1 regarding its origin] can simplify such commands.
52
- Among other things, rexe provides switch-activated input parsing and output formatting so that converting
53
- from one format to another is trivial.
54
- The previous `ruby` command can be expressed in `rexe` as:
45
+ Rexe [see footnote ^1 regarding its origin] can simplify such commands. Among other things, rexe provides switch-activated input parsing and output formatting so that converting from one format to another is trivial. The previous `ruby` command can be expressed in `rexe` as:
55
46
 
56
- ```
47
+ ```bash
57
48
  ➜ ~  echo $EUR_RATES_JSON | rexe -mb -ij -oy self
58
49
  ```
59
50
 
60
51
  Or, even more concisely (`self` is the default Ruby source code for rexe commands):
61
52
 
62
- ```
53
+ ```bash
63
54
  ➜ ~  echo $EUR_RATES_JSON | rexe -mb -ij -oy
64
55
  ```
65
56
 
@@ -69,35 +60,35 @@ The command options may seem cryptic, but they're logical so it shouldn't take l
69
60
  * `-ij` - parse that __input__ with __JSON__; `self` will be the parsed object
70
61
  * `-oy` - __output__ the final value as __YAML__
71
62
 
72
- If input comes from a JSON or YAML file, rexe determines the input format from the file's extension,
73
- and it's even simpler:
63
+ If input comes from a JSON or YAML file, rexe determines the input format from the file's extension, and it's even simpler:
74
64
 
75
- ```
65
+ ```bash
76
66
  ➜ ~  rexe -f eur_rates.json -oy
77
67
  ```
78
68
 
79
- Rexe is at https://github.com/keithrbennett/rexe and can be installed with
80
- `gem install rexe`. Rexe provides several ways to simplify Ruby on the command
81
- line, tipping the scale so that it is practical to do it more often.
69
+ Rexe is at https://github.com/keithrbennett/rexe and can be installed with `gem install rexe`. Rexe provides several ways to simplify Ruby on the command line, tipping the scale so that it is practical to do it more often.
82
70
 
83
71
  ----
84
72
 
85
73
  Here is rexe's help text as of the time of this writing:
86
74
 
87
75
  ```
88
- rexe -- Ruby Command Line Executor/Filter -- v1.0.0 -- https://github.com/keithrbennett/rexe
76
+ rexe -- Ruby Command Line Executor/Filter -- v1.0.1 -- https://github.com/keithrbennett/rexe
89
77
 
90
- Executes Ruby code on the command line, optionally automating management of standard input
91
- and standard output, and optionally parsing input and formatting output with YAML, JSON, etc.
78
+ Executes Ruby code on the command line,
79
+ optionally automating management of standard input and standard output,
80
+ and optionally parsing input and formatting output with YAML, JSON, etc.
92
81
 
93
82
  rexe [options] [Ruby source code]
94
83
 
95
84
  Options:
96
85
 
97
86
  -c --clear_options Clear all previous command line options specified up to now
98
- -f --input_file Use this file instead of stdin; autodetects YAML and JSON file extensions
99
- If YAML or JSON: parses file in that mode, sets input mode to -mb
100
- -g --log_format FORMAT Log format, logs to stderr, defaults to none (see -o for format options)
87
+ -f --input_file Use this file instead of stdin for preprocessed input;
88
+ if filespec has a YAML and JSON file extension,
89
+ sets input format accordingly and sets input mode to -mb
90
+ -g --log_format FORMAT Log format, logs to stderr, defaults to none
91
+ (see -o for format options)
101
92
  -h, --help Print help and exit
102
93
  -i, --input_format FORMAT Input format
103
94
  -ij JSON
@@ -106,13 +97,14 @@ Options:
106
97
  -iy YAML
107
98
  -l, --load RUBY_FILE(S) Ruby file(s) to load, comma separated;
108
99
  ! to clear all, or precede a name with '-' to remove
109
- -m, --input_mode MODE Mode with which to handle input (i.e. what `self` will be in your code):
110
- -ml line mode; each line is ingested as a separate string
111
- -me enumerator mode
112
- -mb big string mode; all lines combined into single multiline string
113
- -mn (default) no input mode; no special handling of input; self is an Object.new
114
- -n, --[no-]noop Do not execute the code (useful with -g); the following are valid:
115
- -n no, -n yes, -n false, -n true, -n n, -n y, -n +, but not -n -
100
+ -m, --input_mode MODE Input preprocessing mode (determines what `self` will be):
101
+ -ml line; each line is ingested as a separate string
102
+ -me enumerator (each_line on STDIN or File)
103
+ -mb big string; all lines combined into one string
104
+ -mn none (default); no input preprocessing;
105
+ self is an Object.new
106
+ -n, --[no-]noop Do not execute the code (useful with -g);
107
+ For true: yes, true, y, +; for false: no, false, n
116
108
  -o, --output_format FORMAT Output format (defaults to puts):
117
109
  -oi Inspect
118
110
  -oj JSON
@@ -132,7 +124,7 @@ In many cases you will need to enclose your source code in single or double quot
132
124
  If source code is not specified, it will default to 'self',
133
125
  which is most likely useful only in a filter mode (-ml, -me, -mb).
134
126
 
135
- If there is an .rexerc file in your home directory, it will be run as Ruby code
127
+ If there is a .rexerc file in your home directory, it will be run as Ruby code
136
128
  before processing the input.
137
129
 
138
130
  If there is a REXE_OPTIONS environment variable, its content will be prepended
@@ -151,27 +143,23 @@ There are two main ways we can make the rexe command line even more concise:
151
143
 
152
144
  ### The REXE_OPTIONS Environment Variable
153
145
 
154
- The `REXE_OPTIONS` environment variable can contain command line options that would otherwise
155
- be specified on the rexe command line:
146
+ The `REXE_OPTIONS` environment variable can contain command line options that would otherwise be specified on the rexe command line:
156
147
 
157
148
  Instead of this:
158
149
 
159
- ```
160
- ➜ ~  rexe -r wifi-wand -oa WifiWand::MacOsModel.new.wifi_info
150
+ ```bash
151
+ ➜ ~  rexe -r wifi-wand -oa WifiWand::MacOsModel.new.wifi_info
161
152
  ```
162
153
 
163
154
  you can do this:
164
155
 
165
- ```
156
+ ```bash
166
157
  ➜ ~  export REXE_OPTIONS="-r wifi-wand -oa"
167
158
  ➜ ~  rexe WifiWand::MacOsModel.new.wifi_info
168
159
  ➜ ~  # [more rexe commands with the same options]
169
160
  ```
170
161
 
171
- Putting configuration options in `REXE_OPTIONS` effectively creates custom defaults,
172
- and is useful when you use the same options in most or all of your commands.
173
- Any options specified on the rexe
174
- command line will override the environment variable options.
162
+ Putting configuration options in `REXE_OPTIONS` effectively creates custom defaults, and is useful when you use the same options in most or all of your commands. Any options specified on the rexe command line will override the environment variable options.
175
163
 
176
164
  Like any environment variable, `REXE_OPTIONS` could also be set in your startup script, input on a command line using `export`, or in another script loaded with `source` or `.`.
177
165
 
@@ -181,42 +169,30 @@ The environment variable approach works well for command line _options_, but wha
181
169
 
182
170
  For this, rexe lets you _load_ Ruby files, using the `-l` option, or implicitly (without your specifying it) in the case of the `~/.rexerc` file. Here is an example of something you might include in such a file:
183
171
 
184
- ```
172
+ ```ruby
185
173
  # Open YouTube to Wagner's "Ride of the Valkyries"
186
174
  def valkyries
187
175
  `open "http://www.youtube.com/watch?v=P73Z6291Pt8&t=0m28s"`
188
176
  end
189
177
  ```
190
178
 
191
- To digress a bit, why would you want this? You might want to be able to go to another room
192
- until a long job completes, and be notified when it is done.
193
- The `valkyries` method will launch a browser window pointed
194
- to Richard Wagner's "Ride of the Valkyries"
195
- starting at a lively point in the music [see footnote ^2 regarding autoplay].
196
- (The `open` command is Mac specific and could be replaced with `start` on Windows,
197
- a browser command name, etc.) [see footnote ^3 regarding OS portability].
179
+ To digress a bit, why would you want this? You might want to be able to go to another room until a long job completes, and be notified when it is done. The `valkyries` method will launch a browser window pointed to Richard Wagner's "Ride of the Valkyries" starting at a lively point in the music [see footnote ^2 regarding autoplay]. (The `open` command is Mac specific and could be replaced with `start` on Windows, a browser command name, etc.) [see footnote ^3 regarding OS portability].
198
180
 
199
181
  If you like this kind of audio notification, you could download public domain audio files and use a command like player like `afplay` on Mac OS, or `mpg123` or `ogg123` on Linux. This approach is lighter weight, requires no network access, and will not leave an open browser window for you to close.
200
182
 
201
- Here is an example of how you might use the `valkyries` method, assuming the above configuration
202
- is loaded from your `~/.rexerc` file or an explicitly loaded file:
183
+ Here is an example of how you might use the `valkyries` method, assuming the above configuration is loaded from your `~/.rexerc` file or an explicitly loaded file:
203
184
 
204
- ```
185
+ ```bash
205
186
  ➜ ~  tar czf /tmp/my-whole-user-space.tar.gz ~ ; rexe valkyries
206
187
  ```
207
188
 
208
189
  (Note that `;` is used rather than `&&` because we want to hear the music whether or not the command succeeds.)
209
190
 
210
- You might be thinking that creating an alias or a minimal shell script (instead of a Ruby script)
211
- for this `open` would be a simpler and more natural
212
- approach, and I would agree with you. However, over time the number of these could become unmanageable, whereas using Ruby
213
- you could build a pretty extensive and well organized library of functionality.
214
- Moreover, that functionality could be made available to _all_ your Ruby code
215
- (for example, by putting it in a gem), and not just command line one liners.
191
+ You might be thinking that creating an alias or a minimal shell script (instead of a Ruby script) for this `open` would be a simpler and more natural approach, and I would agree with you. However, over time the number of these could become unmanageable, whereas using Ruby you could build a pretty extensive and well organized library of functionality. Moreover, that functionality could be made available to _all_ your Ruby code (for example, by putting it in a gem), and not just command line one liners.
216
192
 
217
193
  For example, you could have something like this in a gem or loaded file:
218
194
 
219
- ```
195
+ ```ruby
220
196
  def play(piece_code)
221
197
  pieces = {
222
198
  hallelujah: "https://www.youtube.com/watch?v=IUZEtVbJT5c&t=0m20s",
@@ -230,31 +206,27 @@ end
230
206
 
231
207
  ...which you could then call like this:
232
208
 
233
- ```
209
+ ```bash
234
210
  ➜ ~  tar czf /tmp/my-whole-user-space.tar.gz ~ ; rexe 'play(:hallelujah)'
235
211
  ```
236
212
 
237
- (You need to quote the `play` call because otherwise the shell will process and remove the parentheses.
238
- Alternatively you could escape the parentheses with backslashes.)
213
+ (You need to quote the `play` call because otherwise the shell will process and remove the parentheses. Alternatively you could escape the parentheses with backslashes.)
239
214
 
240
215
  One of the examples at the end of this articles shows how you could have different music play for success and failure.
241
216
 
242
217
 
243
218
  ### Logging
244
219
 
245
- A log entry is optionally output to standard error after completion of the code.
246
- This entry is a hash representation (to be precise, `to_h`) of the `$RC` OpenStruct described in the $RC section below.
247
- It contains the version, date/time of execution, source code
248
- to be evaluated, options (after parsing both the `REXE_OPTIONS` environment variable and the command line),
249
- and the execution time of your Ruby code:
220
+ A log entry is optionally output to standard error after completion of the code. This entry is a hash representation (to be precise, `to_h`) of the `$RC` OpenStruct described in the $RC section below. It contains the version, date/time of execution, source code to be evaluated, options (after parsing both the `REXE_OPTIONS` environment variable and the command line), and the execution time of your Ruby code:
250
221
 
222
+ ```bash
223
+ ➜ ~  echo $EUR_RATES_JSON | rexe -gy -ij -mb -oa -n self
251
224
  ```
252
- ➜ ~  echo $EUR_RATES_JSON | rexe -gy -ij -mb -oa self
253
- ...
225
+ ```yaml
254
226
  ---
255
- :count: 1
227
+ :count: 0
256
228
  :rexe_version: 1.0.0
257
- :start_time: '2019-04-14T19:15:50+08:00'
229
+ :start_time: '2019-04-15T13:12:15+08:00'
258
230
  :source_code: self
259
231
  :options:
260
232
  :input_filespec:
@@ -267,68 +239,54 @@ and the execution time of your Ruby code:
267
239
  - json
268
240
  - yaml
269
241
  :log_format: :yaml
270
- :noop: false
271
- :duration_secs: 0.064798
272
- ```
242
+ :noop: true
243
+ :duration_secs: 0.050326
244
+ ```
273
245
 
274
- We specified `-gy` for YAML format; there are other formats as well (see the help output or this document)
275
- and the default is `-gn`, which means don't output the log entry at all.
246
+ We specified `-gy` for YAML format; there are other formats as well (see the help output or this document) and the default is `-gn`, which means don't output the log entry at all.
276
247
 
277
- The requires you see were not explicitly specified but were automatically added because
278
- Rexe will add any requires needed for automatic parsing and formatting, and
279
- we specified those formats in the command line options `-gy -ij -oa`.
248
+ The requires you see were not explicitly specified but were automatically added because Rexe will add any requires needed for automatic parsing and formatting, and we specified those formats in the command line options `-gy -ij -oa`.
280
249
 
281
- This extra output is sent to standard error (_stderr_) instead of standard output
282
- (_stdout_) so that it will not pollute the "real" data when stdout is piped to
283
- another command.
250
+ This extra output is sent to standard error (_stderr_) instead of standard output (_stdout_) so that it will not pollute the "real" data when stdout is piped to another command.
284
251
 
285
252
  If you would like to append this informational output to a file(e.g. `rexe.log`), you could do something like this:
286
253
 
287
- ```
254
+ ```bash
288
255
  ➜ ~  rexe ... -gy 2>>rexe.log
289
256
  ```
290
257
 
291
258
 
292
259
  ### Input Modes
293
260
 
294
- Rexe tries to make it simple and convenient for you to handle standard input,
295
- and in different ways. Here is the help text relating to input modes:
261
+ Rexe tries to make it simple and convenient for you to handle standard input, and in different ways. Here is the help text relating to input modes:
296
262
 
297
263
  ```
298
- -m, --input_mode MODE Mode with which to handle input (i.e. what `self` will be in your code):
299
- -ml line mode; each line is ingested as a separate string
300
- -me enumerator mode
301
- -mb big string mode; all lines combined into single multiline string
302
- -mn (default) no input mode; no special handling of input; self is an Object.new
264
+ -m, --input_mode MODE Input preprocessing mode (determines what `self` will be):
265
+ -ml line; each line is ingested as a separate string
266
+ -me enumerator (each_line on STDIN or File)
267
+ -mb big string; all lines combined into one string
268
+ -mn none (default); no input preprocessing;
269
+ self is an Object.new
303
270
  ```
304
271
 
305
- The first three are _filter_ modes; they make standard input available
306
- to your code as `self`.
272
+ The first three are _filter_ modes; they make standard input available to your code as `self`.
307
273
 
308
- The last (and default) is the _executor_ mode. It merely assists you in
309
- executing the code you provide without any special implicit handling of standard input.
310
- Here is more detail on these modes:
274
+ The last (and default) is the _executor_ mode. It merely assists you in executing the code you provide without any special implicit handling of standard input. Here is more detail on these modes:
311
275
 
312
276
 
313
277
  #### -ml "Line" Filter Mode
314
278
 
315
- In this mode, your code would be called once per line of input,
316
- and in each call, `self` would evaluate to each line of text:
279
+ In this mode, your code would be called once per line of input, and in each call, `self` would evaluate to each line of text:
317
280
 
318
- ```
281
+ ```bash
319
282
  ➜ ~  echo "hello\ngoodbye" | rexe -ml puts reverse
320
283
  olleh
321
284
  eybdoog
322
285
  ```
323
286
 
324
- `reverse` is implicitly called on each line of standard input. `self`
325
- is the input line in each call (we could also have used `self.reverse` but the `self.` would have been redundant).
287
+ `reverse` is implicitly called on each line of standard input. `self` is the input line in each call (we could also have used `self.reverse` but the `self.` would have been redundant).
326
288
 
327
- Be aware that, in this mode, if you are using an automatic output mode
328
- (anything other than the default `-on` no output mode),
329
- although you can control the _content_ of output records,
330
- there is no way to selectively _exclude_ records from being output. Even if the result of the code
331
- is nil or the empty string, a newline will be output. To prevent this, you can do one of the following:
289
+ Be aware that, in this mode, if you are using an automatic output mode (anything other than the default `-on` no output mode), although you can control the _content_ of output records, there is no way to selectively _exclude_ records from being output. Even if the result of the code is nil or the empty string, a newline will be output. To prevent this, you can do one of the following:
332
290
 
333
291
  * use `-me` Enumerator mode instead and call `select`, `filter`, `reject`, etc.
334
292
  * use the (default) `-on` _no output_ mode and call `puts` explicitly for the output you _do_ want
@@ -336,16 +294,13 @@ is nil or the empty string, a newline will be output. To prevent this, you can d
336
294
 
337
295
  #### -me "Enumerator" Filter Mode
338
296
 
339
- In this mode, your code is called only once, and `self` is an enumerator
340
- dispensing all lines of standard input. To be more precise, it is the enumerator returned by the `each_line` method,
341
- on `$stdin` or the input file, whichever is applicable.
297
+ In this mode, your code is called only once, and `self` is an enumerator dispensing all lines of standard input. To be more precise, it is the enumerator returned by the `each_line` method, on `$stdin` or the input file, whichever is applicable.
342
298
 
343
299
  Dealing with input as an enumerator enables you to use the wealth of `Enumerable` methods such as `select`, `to_a`, `map`, etc.
344
300
 
345
- Here is an example of using `-me` to add line numbers to the first 3
346
- files in the directory listing:
301
+ Here is an example of using `-me` to add line numbers to the first 3 files in the directory listing:
347
302
 
348
- ```
303
+ ```bash
349
304
  ➜ ~  ls / | rexe -me "first(3).each_with_index { |ln,i| puts '%5d %s' % [i, ln] }"
350
305
 
351
306
  0 AndroidStudioProjects
@@ -353,34 +308,26 @@ files in the directory listing:
353
308
  2 Desktop
354
309
  ```
355
310
 
356
- Since `self` is an enumerable, we can call `first` on it.
357
- We've used the default output mode `-on` (_no output_ mode), which says don't do any automatic output,
358
- just the output explicitly specified by `puts` in the source code.
311
+ Since `self` is an enumerable, we can call `first` on it. We've used the default output mode `-on` (_no output_ mode), which says don't do any automatic output, just the output explicitly specified by `puts` in the source code.
359
312
 
360
313
 
361
314
  #### -mb "Big String" Filter Mode
362
315
 
363
- In this mode, all standard input is combined into a single (possibly
364
- large and possibly multiline) string.
316
+ In this mode, all standard input is combined into a single (possibly large and possibly multiline) string.
365
317
 
366
- A good example of when you would use this is when you need to parse a multiline JSON or YAML representation of an object;
367
- you need to pass all the standard input to the parse method.
368
- This is the mode that was used in the first rexe example in this article.
318
+ A good example of when you would use this is when you need to parse a multiline JSON or YAML representation of an object; you need to pass all the standard input to the parse method. This is the mode that was used in the first rexe example in this article.
369
319
 
370
320
 
371
321
  #### -mn "No Input" Executor Mode -- The Default
372
322
 
373
- In this mode, no special handling of standard input is done at all;
374
- if you want standard input you need to code it yourself (e.g. with `STDIN.read`).
323
+ In this mode, no special handling of standard input is done at all; if you want standard input you need to code it yourself (e.g. with `STDIN.read`).
375
324
 
376
- `self` evaluates to a new instance of `Object`, which would be used
377
- if you defined methods, constants, instance variables, etc., in your code.
325
+ `self` evaluates to a new instance of `Object`, which would be used if you defined methods, constants, instance variables, etc., in your code.
378
326
 
379
327
 
380
328
  #### Filter Input Mode Memory Considerations
381
329
 
382
- If you are using one of the filter modes, and may have more input than would fit in memory,
383
- you can do one of the following:
330
+ If you are using one of the filter modes, and may have more input than would fit in memory, you can do one of the following:
384
331
 
385
332
  * use `-ml` (line) mode so you are fed only 1 line at a time
386
333
  * use an Enumerator, either by a) specifying the `-me` (enumerator) mode option,
@@ -392,20 +339,16 @@ you can do one of the following:
392
339
 
393
340
  ### Input Formats
394
341
 
395
- Rexe can parse your input in any of several formats if you like.
396
- You would request this in the _input format_ (`-i`) option.
397
- Legal values are:
342
+ Rexe can parse your input in any of several formats if you like. You would request this in the _input format_ (`-i`) option. Legal values are:
398
343
 
399
344
  * `-ij` - JSON
400
345
  * `-im` - Marshal
401
346
  * `-in` - [None] (default)
402
347
  * `-iy` - YAML
403
348
 
404
- Except for `-in`, which passes the text to your code untouched, your input will be parsed
405
- in the specified format, and the resulting object passed into your code as `self`.
349
+ Except for `-in`, which passes the text to your code untouched, your input will be parsed in the specified format, and the resulting object passed into your code as `self`.
406
350
 
407
- The input format option is ignored if the input _mode_ is `-mn` ("no input" executor mode, the default),
408
- since there is no preprocessing of standard input in that mode.
351
+ The input format option is ignored if the input _mode_ is `-mn` ("no input" executor mode, the default), since there is no preprocessing of standard input in that mode.
409
352
 
410
353
  ### Output Formats
411
354
 
@@ -422,11 +365,9 @@ Several output formats are provided for your convenience:
422
365
 
423
366
  All formats will implicitly `require` anything needed to accomplish their task (e.g. `require 'yaml'`).
424
367
 
425
- The default is `-on` to produce no output at all (unless explicitly coded to do so). If you prefer a different
426
- default such as `-op` for _puts_ mode, you can specify that in your `REXE_OPTIONS` environment variable.
368
+ The default is `-on` to produce no output at all (unless explicitly coded to do so). If you prefer a different default such as `-op` for _puts_ mode, you can specify that in your `REXE_OPTIONS` environment variable.
427
369
 
428
- You may wonder why these formats are provided, given that their functionality
429
- could be included in the custom code instead. Here's why:
370
+ You may wonder why these formats are provided, given that their functionality could be included in the custom code instead. Here's why:
430
371
 
431
372
  * The savings in command line length goes a long way to making these commands more readable and feasible.
432
373
  * It's much simpler to switch formats, as there is no need to change the code itself.
@@ -435,44 +376,40 @@ could be included in the custom code instead. Here's why:
435
376
 
436
377
  ### Reading Input from a File
437
378
 
438
- Rexe also simplifies getting input from a file rather than standard input. The `-f` option takes a filespec
439
- and does with its content exactly what it would have done with standard input. This shortens:
379
+ Rexe also simplifies getting input from a file rather than standard input. The `-f` option takes a filespec and does with its content exactly what it would have done with standard input. This shortens:
440
380
 
441
- ```
381
+ ```bash
442
382
  ➜ ~  cat filename.ext | rexe ...
443
383
  ```
444
384
  ...to...
445
385
 
446
- ```
386
+ ```bash
447
387
  ➜ ~  rexe -f filename.ext ...
448
388
  ```
449
389
 
450
- This becomes even more useful if you are using files whose extensions are `.yml`, `.yaml`, or `.json` (case insensitively).
451
- In this case the input format and mode will be set automatically for you to:
390
+ This becomes even more useful if you are using files whose extensions are `.yml`, `.yaml`, or `.json` (case insensitively). In this case the input format and mode will be set automatically for you to:
452
391
 
453
392
  * `-iy` (YAML) or `-ij` (JSON) depending on the file extension
454
393
  * `-mb` (one big string mode), which assumes that the most common use case will be to parse the entire file at once
455
394
 
456
395
  So the example we gave above:
457
396
 
458
- ```
397
+ ```bash
459
398
  ➜ ~  export EUR_RATES_JSON=`curl https://api.exchangeratesapi.io/latest`
460
399
  ➜ ~  echo $EUR_RATES_JSON | rexe -mb -ij -oy self
461
400
  ```
462
401
  ...could be changed to:
463
402
 
464
- ```
403
+ ```bash
465
404
  ➜ ~  curl https://api.exchangeratesapi.io/latest > eur_rates.json
466
405
  ➜ ~  rexe -f eur_rates.json -oy self
467
406
  ```
468
407
 
469
- Another possible win for using `-f` is that since it is a command line option, it could be specified in `REXE_OPTIONS`.
470
- This could be useful if you are doing many operations on the same file.
408
+ Another possible win for using `-f` is that since it is a command line option, it could be specified in `REXE_OPTIONS`. This could be useful if you are doing many operations on the same file.
471
409
 
472
- If you need to override the input mode and format automatically configured for file input, you can simply specify
473
- the desired options on the command line _after_ the `-f`:
410
+ If you need to override the input mode and format automatically configured for file input, you can simply specify the desired options on the command line _after_ the `-f`:
474
411
 
475
- ```
412
+ ```bash
476
413
  ➜ ~  rexe -f eur_rates.json -mb -in 'puts self.class, self[0..20]'
477
414
  String
478
415
  {"base":"EUR","rates"
@@ -481,15 +418,14 @@ String
481
418
 
482
419
  ### 'self' as Default Source Code
483
420
 
484
- To make rexe even more concise, you do not need to specify any source code when you want that source code
485
- to be `self`. This would be the case for simple format conversions, as in JSON to YAML conversion
486
- mentioned above:
421
+ To make rexe even more concise, you do not need to specify any source code when you want that source code to be `self`. This would be the case for simple format conversions, as in JSON to YAML conversion mentioned above:
487
422
 
488
- ```
423
+ ```bash
489
424
  ➜ ~  rexe -f eur_rates.json -oy
490
425
  # or
491
426
  ➜ ~  echo $EUR_RATES_JSON | rexe -mb -ij -oy
492
-
427
+ ```
428
+ ```yaml
493
429
  ---
494
430
  rates:
495
431
  JPY: 126.63
@@ -498,44 +434,42 @@ rates:
498
434
  ...
499
435
  ```
500
436
 
501
- This feature is probably only useful in the filter modes, since in the executor mode (`-mn`) self is a new
502
- instance of `Object` and hardly ever useful as an output value.
437
+ This feature is probably only useful in the filter modes, since in the executor mode (`-mn`) self is a new instance of `Object` and hardly ever useful as an output value.
503
438
 
504
439
  ### The $RC Global OpenStruct
505
440
 
506
- For your convenience, the information displayed in verbose mode is available to your code at runtime
507
- by accessing the `$RC` global variable, which contains an OpenStruct. Let's print out its contents using AwesomePrint:
441
+ For your convenience, the information displayed in verbose mode is available to your code at runtime by accessing the `$RC` global variable, which contains an OpenStruct. Let's print out its contents using YAML:
508
442
 
509
- ```
510
- ➜ ~  rexe -oa '$RC'
511
- OpenStruct {
512
- :count => 0,
513
- :rexe_version => "1.0.0",
514
- :start_time => "2019-04-14T19:16:26+08:00",
515
- :source_code => "$RC",
516
- :options => {
517
- :input_filespec => nil,
518
- :input_format => :none,
519
- :input_mode => :none,
520
- :loads => [],
521
- :output_format => :awesome_print,
522
- :requires => [
523
- [0] "awesome_print"
524
- ],
525
- :log_format => :none,
526
- :noop => false
527
- }
528
- }
443
+ ```bash
444
+ ➜ ~  rexe -oy '$RC'
445
+ ```
446
+ ```yaml
447
+ --- !ruby/object:OpenStruct
448
+ table:
449
+ :count: 0
450
+ :rexe_version: 1.0.0
451
+ :start_time: '2019-04-15T13:25:56+08:00'
452
+ :source_code: "$RC"
453
+ :options:
454
+ :input_filespec:
455
+ :input_format: :none
456
+ :input_mode: :none
457
+ :loads: []
458
+ :output_format: :yaml
459
+ :requires:
460
+ - yaml
461
+ :log_format: :none
462
+ :noop: false
463
+ modifiable: true
529
464
  ```
530
465
 
531
- Probably most useful in that object at runtime
532
- is the record count, accessible with both `$RC.count` and `$RC.i`.
533
- This is only really useful in line mode, because in the others
534
- it will always be 0 or 1. Here is an example of how you might use it as a kind of progress indicator:
466
+ Probably most useful in that object at runtime is the record count, accessible with both `$RC.count` and `$RC.i`. This is only really useful in line mode, because in the others it will always be 0 or 1. Here is an example of how you might use it as a kind of progress indicator:
535
467
 
536
- ```
468
+ ```bash
537
469
  ➜ ~  find / | rexe -ml -on \
538
470
  'if $RC.i % 1000 == 0; puts %Q{File entry ##{$RC.i} is #{self}}; end'
471
+ ```
472
+ ```
539
473
  ...
540
474
  File entry #106000 is /usr/local/Cellar/go/1.11.5/libexec/src/cmd/vendor/github.com/google/pprof/internal/driver/driver_test.go
541
475
  File entry #107000 is /usr/local/Cellar/go/1.11.5/libexec/src/go/types/testdata/cycles1.src
@@ -543,30 +477,21 @@ File entry #108000 is /usr/local/Cellar/go/1.11.5/libexec/src/runtime/os_linux_n
543
477
  ...
544
478
  ```
545
479
 
546
- Note that a single quote was used for the Ruby code here;
547
- if a double quote were used, the `$RC` would have been interpreted
548
- and removed by the shell.
480
+ Note that a single quote was used for the Ruby code here; if a double quote were used, the `$RC` would have been interpreted and removed by the shell.
549
481
 
550
482
 
551
483
  ### Implementing Domain Specific Languages (DSL's)
552
484
 
553
- Defining methods in your loaded files enables you to effectively define a
554
- [DSL](https://en.wikipedia.org/wiki/Domain-specific_language) for your command line use.
555
- You could use different load files for different projects, domains, or contexts,
556
- and define aliases or one line scripts to give them meaningful names.
557
- For example, if you had Ansible helper code in `~/projects/ansible-tools/rexe-ansible.rb`,
558
- you could define an alias in your startup script:
485
+ Defining methods in your loaded files enables you to effectively define a [DSL](https://en.wikipedia.org/wiki/Domain-specific_language) for your command line use. You could use different load files for different projects, domains, or contexts, and define aliases or one line scripts to give them meaningful names. For example, if you had Ansible helper code in `~/projects/ansible-tools/rexe-ansible.rb`, you could define an alias in your startup script:
559
486
 
560
- ```
487
+ ```bash
561
488
  ➜ ~  alias rxans="rexe -l ~/projects/ansible-tools/rexe-ansible.rb $*"
562
489
  ```
563
490
  ...and then you would have an Ansible DSL available for me to use by calling `rxans`.
564
491
 
565
- In addition, since you can also call `pry` on the context of any object, you
566
- can provide a DSL in a [REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop) (shell)
567
- trivially easily. Just to illustrate, here's how you would open a REPL on the File class:
492
+ In addition, since you can also call `pry` on the context of any object, you can provide a DSL in a [REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop) (shell) trivially easily. Just to illustrate, here's how you would open a REPL on the File class:
568
493
 
569
- ```
494
+ ```bash
570
495
  ➜ ~  ruby -r pry -e File.pry
571
496
  # or
572
497
  ➜ ~  rexe -r pry File.pry
@@ -574,9 +499,10 @@ trivially easily. Just to illustrate, here's how you would open a REPL on the Fi
574
499
 
575
500
  `self` would evaluate to the `File` class, so you could call class methods using only their names:
576
501
 
577
- ```
502
+ ```bash
578
503
  ➜ ~  rexe -r pry File.pry
579
-
504
+ ```
505
+ ```
580
506
  [6] pry(File)> size '/etc/passwd'
581
507
  6804
582
508
  [7] pry(File)> directory? '.'
@@ -587,32 +513,28 @@ true
587
513
 
588
514
  This could be really handy if you call `pry` on a custom object that has methods especially suited to your task:
589
515
 
590
- ```
516
+ ```bash
591
517
  ➜ ~  rexe -r wifi-wand,pry WifiWand::MacOsModel.new.pry
518
+ ```
519
+ ```
592
520
  [1] pry(#<WifiWand::MacOsModel>)> random_mac_address
593
521
  "a1:ea:69:d9:ca:05"
594
522
  [2] pry(#<WifiWand::MacOsModel>)> connected_network_name
595
523
  "My WiFi"
596
524
  ```
597
525
 
598
- Ruby is supremely well suited for DSL's since it does not require parentheses for method calls,
599
- so calls to your custom methods _look_ like built in language commands and keywords.
526
+ Ruby is supremely well suited for DSL's since it does not require parentheses for method calls, so calls to your custom methods _look_ like built in language commands and keywords.
600
527
 
601
528
 
602
529
  ### Quotation Marks and Quoting Strings in Your Ruby Code
603
530
 
604
- One complication of using utilities like rexe where Ruby code is specified on the command line is that
605
- you need to be careful about the shell's special treatment of certain characters. For this reason, it is often
606
- necessary to quote the Ruby code. You can use single or double quotes to have the shell treat your source code
607
- as a single argument. An excellent reference for how they differ is on StackOverflow at
608
- https://stackoverflow.com/questions/6697753/difference-between-single-and-double-quotes-in-bash.
531
+ One complication of using utilities like rexe where Ruby code is specified on the command line is that you need to be careful about the shell's special treatment of certain characters. For this reason, it is often necessary to quote the Ruby code. You can use single or double quotes to have the shell treat your source code as a single argument. An excellent reference for how they differ is on StackOverflow at https://stackoverflow.com/questions/6697753/difference-between-single-and-double-quotes-in-bash.
609
532
 
610
- Personally, I find single quotes more useful since I usually don't want special characters in my Ruby code
611
- like `$` to be processed by the shell.
533
+ Personally, I find single quotes more useful since I usually don't want special characters in my Ruby code like `$` to be processed by the shell.
612
534
 
613
535
  Sometimes it doesn't matter:
614
536
 
615
- ```
537
+ ```bash
616
538
  ➜ ~  rexe 'puts "hello"'
617
539
  hello
618
540
  ➜ ~  rexe "puts 'hello'"
@@ -621,67 +543,65 @@ hello
621
543
 
622
544
  We can also use `%q` or `%Q`, and sometimes this eliminates the needs for the outer quotes altogether:
623
545
 
624
- ```
546
+ ```bash
625
547
  ➜ ~  rexe puts %q{hello}
626
548
  hello
627
549
  ➜ ~  rexe puts %Q{hello}
628
550
  hello
629
551
  ```
630
552
 
631
- Sometimes the quotes to use on the outside (quoting your command in the shell) need to be chosen
632
- based on which quotes are needed on the inside. For example, in the following command, we need
633
- double quotes in Ruby in order for interpolation to work, so we use single quotes on the outside:
553
+ Sometimes the quotes to use on the outside (quoting your command in the shell) need to be chosen based on which quotes are needed on the inside. For example, in the following command, we need double quotes in Ruby in order for interpolation to work, so we use single quotes on the outside:
634
554
 
635
- ```
555
+ ```bash
636
556
  ➜ ~  rexe puts '"The time is now #{Time.now}"'
557
+ ```
558
+ ```
637
559
  The time is now 2019-03-29 16:41:26 +0800
638
560
  ```
639
561
 
640
- In this case we also need to use single quotes on the outside,
641
- because we need literal double quotes in a `%Q{}` expression:
562
+ In this case we also need to use single quotes on the outside, because we need literal double quotes in a `%Q{}` expression:
642
563
 
643
- ```
564
+ ```bash
644
565
  ➜ ~  rexe 'puts %Q{The operating system name is "#{`uname`.chomp}".}'
566
+ ```
567
+ ```
645
568
  The operating system name is "Darwin".
646
569
  ```
647
570
 
648
571
  We can eliminate the need for any quotes in the Ruby code using `%Q{}`:
649
572
 
650
- ```
573
+ ```bash
651
574
  ➜ ~  rexe puts '%Q{The time is now #{Time.now}}'
575
+ ```
576
+ ```
652
577
  The time is now 2019-03-29 17:06:13 +0800
653
578
  ```
654
579
 
655
580
  Of course you can always escape the quotes with backslashes instead, but that is probably more difficult to read.
656
581
 
657
582
 
658
-
659
-
660
583
  ### No Op Mode
661
584
 
662
- The `-n` no-op mode will result in the specified source code _not_ being executed. This can sometimes be handy
663
- in conjunction with a `-g` (logging) option, if you have are building a rexe command and
664
- want to inspect the configuration options before executing the Ruby code.
585
+ The `-n` no-op mode will result in the specified source code _not_ being executed. This can sometimes be handy in conjunction with a `-g` (logging) option, if you have are building a rexe command and want to inspect the configuration options before executing the Ruby code.
665
586
 
666
587
 
667
588
  ### Mimicking Method Arguments
668
589
 
669
- You may want to support arguments in your rexe commands.
670
- It's a little kludgy, but you could do this by piping in the arguments as rexe's stdin.
590
+ You may want to support arguments in your rexe commands. It's a little kludgy, but you could do this by piping in the arguments as rexe's stdin.
671
591
 
672
- One of the previous examples downloaded currency conversion rates.
673
- To prepare for an example of how to do this, let's find out the available currency codes:
592
+ One of the previous examples downloaded currency conversion rates. To prepare for an example of how to do this, let's find out the available currency codes:
674
593
 
675
- ```
594
+ ```bash
676
595
  ➜ /  echo $EUR_RATES_JSON | \
677
596
  rexe -ij -mb -op "self['rates'].keys.sort.join(' ')"
597
+ ```
598
+ ```
678
599
  AUD BGN BRL CAD CHF CNY CZK DKK GBP HKD HRK HUF IDR ILS INR ISK JPY KRW MXN MYR NOK NZD PHP PLN RON RUB SEK SGD THB TRY USD ZAR
679
600
  ```
680
601
 
681
- The codes output are the legal arguments that could be sent to rexe's stdin as an argument in the command below.
682
- Let's find out the Euro exchange rate for _PHP_, Philippine Pesos:
602
+ The codes output are the legal arguments that could be sent to rexe's stdin as an argument in the command below. Let's find out the Euro exchange rate for _PHP_, Philippine Pesos:
683
603
 
684
- ```
604
+ ```bash
685
605
  ➜ ~  echo PHP | rexe -ml -op -rjson \
686
606
  "rate = JSON.parse(ENV['EUR_RATES_JSON'])['rates'][self];\
687
607
  %Q{1 EUR = #{rate} #{self}}"
@@ -689,88 +609,78 @@ Let's find out the Euro exchange rate for _PHP_, Philippine Pesos:
689
609
  1 EUR = 58.986 PHP
690
610
  ```
691
611
 
692
- In this code, `self` is the currency code `PHP` (Philippine Peso).
693
- We have accessed the JSON text to parse from the environment variable we previously populated.
612
+ In this code, `self` is the currency code `PHP` (Philippine Peso). We have accessed the JSON text to parse from the environment variable we previously populated.
694
613
 
695
- Because we "used up" stdin for the `PHP` argument, we needed to read the JSON data explicitly from
696
- the environment variable, and that made the command more complex. A regular Ruby script would handle this more nicely.
614
+ Because we "used up" stdin for the `PHP` argument, we needed to read the JSON data explicitly from the environment variable, and that made the command more complex. A regular Ruby script would handle this more nicely.
697
615
 
698
616
 
699
617
  ### Using the Clipboard for Text Processing
700
618
 
701
- For editing text in an editor,
702
- rexe can be used for text transformations that would otherwise need to be done manually.
619
+ For editing text in an editor, rexe can be used for text transformations that would otherwise need to be done manually.
703
620
 
704
- The system's commands for pasting to and copying from the clipboard can handle the moving of the text
705
- between the editor and rexe. On the Mac, we have the following commands:
621
+ The system's commands for pasting to and copying from the clipboard can handle the moving of the text between the editor and rexe. On the Mac, we have the following commands:
706
622
 
707
623
  * `pbcopy` - copies the content of its stdin _to_ the clipboard
708
624
  * `pbpaste` - copies the content _from_ the clipboard to its stdout
709
625
 
710
- Let's say we have the following currency codes displayed on the screen
711
- (data abridged for brevity):
626
+ Let's say we have the following currency codes displayed on the screen (data abridged for brevity):
712
627
 
713
628
  ```
714
629
  AUD BGN BRL PHP TRY USD ZAR
715
630
  ```
716
631
 
717
- ...and we want to turn them into Ruby symbols for inclusion in Ruby source code as keys in a hash
718
- whose values will be the display names of the currencies, e.g "Australian Dollar").
632
+ ...and we want to turn them into Ruby symbols for inclusion in Ruby source code as keys in a hash whose values will be the display names of the currencies, e.g "Australian Dollar").
719
633
 
720
- We could manually select that text and use system menu commands or keys to copy it to the clipboard,
721
- or we could do this:
634
+ We could manually select that text and use system menu commands or keys to copy it to the clipboard, or we could do this:
722
635
 
723
- ```
636
+ ```bash
724
637
  ➜ ~  echo AUD BGN BRL PHP TRY USD ZAR | pbcopy
725
638
  ```
726
639
 
727
640
  After copying this line to the clipboard, we could run this:
728
641
 
729
- ```
730
- ➜ ~  pbpaste | rexe -ml -op "split.map(&:downcase).map { |s| %Q{ #{s}: '',} }.join(%Q{\n})"
642
+ ```bash
643
+ ➜ ~  pbpaste | rexe -ml -op \
644
+ "split.map(&:downcase).map { |s| %Q{ #{s}: '',} }.join(%Q{\n})"
731
645
  aud: '',
732
646
  bgn: '',
733
647
  brl: '',
734
648
  # ...
735
649
  ```
736
650
 
737
- If I add `| pbcopy` to the rexe command, then that output text would be copied into the clipboard instead of
738
- displayed in the terminal, and I could then paste it into my editor.
651
+ If I add `| pbcopy` to the rexe command, then that output text would be copied into the clipboard instead of displayed in the terminal, and I could then paste it into my editor.
739
652
 
740
- Using the clipboard in manual operations is handy, but using it in automated scripts is a very bad idea, since
741
- there is only one clipboard per user session. If you use the clipboard in an automated script you risk
742
- an error situation if its content is changed by another process, or, conversely, you could mess up another process
743
- when you change the content of the clipboard.
653
+ Using the clipboard in manual operations is handy, but using it in automated scripts is a very bad idea, since there is only one clipboard per user session. If you use the clipboard in an automated script you risk an error situation if its content is changed by another process, or, conversely, you could mess up another process when you change the content of the clipboard.
744
654
 
745
655
  ### Multiline Ruby Commands
746
656
 
747
- Although rexe is cleanest with short one liners, you may want to use it to include nontrivial Ruby code
748
- in your shell script as well. If you do this, you may need to add trailing backslashes to the lines of Ruby code.
657
+ Although rexe is cleanest with short one liners, you may want to use it to include nontrivial Ruby code in your shell script as well. If you do this, you may need to add trailing backslashes to the lines of Ruby code.
749
658
 
750
- What might not be so obvious is that you will often need to use semicolons as statement separators.
751
- For example, here is an example without a semicolon:
659
+ What might not be so obvious is that you will often need to use semicolons as statement separators. For example, here is an example without a semicolon:
752
660
 
753
- ```
661
+ ```bash
754
662
  ➜ ~  cowsay hello | rexe -me "print %Q{\u001b[33m} \
755
663
  puts to_a"
756
-
664
+ ```
665
+ ```
757
666
  rexe: (eval):1: syntax error, unexpected tIDENTIFIER, expecting '}'
758
667
  ...new { print %Q{\u001b[33m} puts to_a }
759
668
  ... ^~~~
760
669
  ```
761
670
 
762
- The shell combines all backslash terminated lines into a single line of text, so when the Ruby
763
- interpreter sees your code, it's all in a single line:
671
+ The shell combines all backslash terminated lines into a single line of text, so when the Ruby interpreter sees your code, it's all in a single line:
764
672
 
765
- ```
673
+ ```bash
766
674
  ➜ ~  cowsay hello | rexe -me "print %Q{\u001b[33m} puts to_a"
767
675
  ```
768
676
 
769
677
  Adding the semicolon fixes the problem:
770
678
 
771
- ```
679
+ ```bash
772
680
  ➜ ~  cowsay hello | rexe -me "print %Q{\u001b[33m}; \
773
681
  puts to_a"
682
+ ```
683
+ ```
774
684
  _______
775
685
  < hello >
776
686
  -------
@@ -784,17 +694,13 @@ puts to_a"
784
694
 
785
695
  ### Clearing the Require and Load Lists
786
696
 
787
- There may be times when you have specified a load or require on the command line
788
- or in the `REXE_OPTIONS` environment variable,
789
- but you want to override it for a single invocation. Here are your options:
697
+ There may be times when you have specified a load or require on the command line or in the `REXE_OPTIONS` environment variable, but you want to override it for a single invocation. Here are your options:
790
698
 
791
699
  1) Unspecify _all_ the requires or loads with the `-r!` and `-l!` command line options, respectively.
792
700
 
793
- 2) Unspecify individual requires or loads by preceding the name with `-`, e.g. `-r -rails`.
794
- Array subtraction is used, and array subtraction removes _all_
795
- occurrences of each element of the subtracted (subtrahend) array, so:
701
+ 2) Unspecify individual requires or loads by preceding the name with `-`, e.g. `-r -rails`. Array subtraction is used, and array subtraction removes _all_ occurrences of each element of the subtracted (subtrahend) array, so:
796
702
 
797
- ```
703
+ ```bash
798
704
  ➜ ~  rexe -n -r rails,rails,rails,-rails -gP
799
705
  ...
800
706
  :requires=>["pp"],
@@ -805,7 +711,7 @@ occurrences of each element of the subtracted (subtrahend) array, so:
805
711
 
806
712
  We could have also extracted the requires list programmatically using `$RC` (described above) by doing this:
807
713
 
808
- ```
714
+ ```bash
809
715
  ➜ ~  rexe -oP -r rails,rails,rails,-rails '$RC[:options][:requires]'
810
716
  ["pp"]
811
717
  ```
@@ -813,17 +719,14 @@ We could have also extracted the requires list programmatically using `$RC` (des
813
719
 
814
720
  ### Clearing _All_ Options
815
721
 
816
- You can also clear _all_ options specified up to a certain point in time with the _clear options_ option (`-c`).
817
- This is especially useful if you have specified options in the `REXE_OPTIONS` environment variable,
818
- and want to ignore all of them.
722
+ You can also clear _all_ options specified up to a certain point in time with the _clear options_ option (`-c`). This is especially useful if you have specified options in the `REXE_OPTIONS` environment variable, and want to ignore all of them.
819
723
 
820
724
 
821
725
  ### Comma Separated Requires and Loads
822
726
 
823
- For consistency with the `ruby` interpreter, rexe supports requires with the `-r` option, but
824
- also allows grouping them together using commas:
727
+ For consistency with the `ruby` interpreter, rexe supports requires with the `-r` option, but also allows grouping them together using commas:
825
728
 
826
- ```
729
+ ```bash
827
730
  vvvvvvvvvvvvvvvvvvvvv
828
731
  ➜ ~  echo $EUR_RATES_JSON | rexe -r json,awesome_print 'ap JSON.parse(STDIN.read)'
829
732
  ^^^^^^^^^^^^^^^^^^^^^
@@ -836,7 +739,7 @@ Files loaded with the `-l` option are treated the same way.
836
739
 
837
740
  Requiring gems and modules for _all_ invocations of rexe will make your commands simpler and more concise, but will be a waste of execution time if they are not needed. You can inspect the execution times to see just how much time is being consumed. For example, we can find out that rails takes about 0.63 seconds to load on one system by observing and comparing the execution times with and without the require (output has been abbreviated using `grep`):
838
741
 
839
- ```
742
+ ```bash
840
743
  ➜ ~  rexe -gy -r rails 2>&1 | grep duration
841
744
  :duration_secs: 0.660138
842
745
  ➜ ~  rexe -gy 2>&1 | grep duration
@@ -847,9 +750,7 @@ Requiring gems and modules for _all_ invocations of rexe will make your commands
847
750
 
848
751
  ### Operating System Support
849
752
 
850
- Rexe has been tested successfully on Mac OS, Linux, and Windows Subsystem for Linux (WSL).
851
- It is intended as a tool for the Unix shell, and, as such, no attempt is made to support
852
- Windows non-Unix shells.
753
+ Rexe has been tested successfully on Mac OS, Linux, and Windows Subsystem for Linux (WSL). It is intended as a tool for the Unix shell, and, as such, no attempt is made to support Windows non-Unix shells.
853
754
 
854
755
 
855
756
  ### More Examples
@@ -862,29 +763,28 @@ Here are some more examples to illustrate the use of rexe.
862
763
 
863
764
  To output the result to stdout, you can either call `puts` or specify the `-op` option:
864
765
 
865
- ```
766
+ ```bash
866
767
  ➜ ~  rexe puts 1 / 3.0
867
768
  0.3333333333333333
868
769
  ```
869
770
 
870
771
  or:
871
772
 
872
- ```
773
+ ```bash
873
774
  ➜ ~  rexe -op 1 / 3.0
874
775
  0.3333333333333333
875
776
  ```
876
777
 
877
778
  Since `*` is interpreted by the shell, if we do multiplication, we need to quote the expression:
878
779
 
879
- ```
780
+ ```bash
880
781
  ➜ ~  rexe -op '2 * 7'
881
782
  14
882
783
  ```
883
784
 
884
- Of course, if you put the `-op` in the `REXE_OPTIONS` environment variable,
885
- you don't need to be explicit about the output:
785
+ Of course, if you put the `-op` in the `REXE_OPTIONS` environment variable, you don't need to be explicit about the output:
886
786
 
887
- ```
787
+ ```bash
888
788
  ➜ ~  export REXE_OPTIONS=-op
889
789
  ➜ ~  rexe '2 * 7'
890
790
  14
@@ -897,8 +797,10 @@ you don't need to be explicit about the output:
897
797
 
898
798
  Output the contents of `ENV` using AwesomePrint [see footnote ^4 regarding ENV.to_s]:
899
799
 
900
- ```
800
+ ```bash
901
801
  ➜ ~  rexe -oa ENV
802
+ ```
803
+ ```
902
804
  {
903
805
  ...
904
806
  "LANG" => "en_US.UTF-8",
@@ -914,7 +816,7 @@ Output the contents of `ENV` using AwesomePrint [see footnote ^4 regarding ENV.t
914
816
 
915
817
  Show disk space used/free on a Mac's main hard drive's main partition:
916
818
 
917
- ```
819
+ ```bash
918
820
  ➜ ~  df -h | grep disk1s1 | rexe -ml \
919
821
  "x = split; puts %Q{#{x[4]} Used: #{x[2]}, Avail: #{x[3]}}"
920
822
  91% Used: 412Gi, Avail: 44Gi
@@ -928,29 +830,29 @@ Show disk space used/free on a Mac's main hard drive's main partition:
928
830
 
929
831
  Show the 3 longest file names of the current directory, with their lengths, in descending order:
930
832
 
931
- ```
833
+ ```bash
932
834
  ➜ ~  ls | rexe -ml -op "%Q{[%4d] %s} % [length, self]" | sort -r | head -3
933
835
  [ 50] Agoda_Booking_ID_9999999 49_–_RECEIPT_enclosed.pdf
934
836
  [ 40] 679a5c034994544aab4635ecbd50ab73-big.jpg
935
837
  [ 28] 2018-abc-2019-01-16-2340.zip
936
838
  ```
937
839
 
938
- When you right align numbers using printf formatting, sorting the lines
939
- alphabetically will result in sorting them numerically as well.
840
+ When you right align numbers using printf formatting, sorting the lines alphabetically will result in sorting them numerically as well.
940
841
 
941
842
  ----
942
843
 
943
844
  #### Print yellow (trust me!):
944
845
 
945
- This uses an [ANSI escape code](https://en.wikipedia.org/wiki/ANSI_escape_code)
946
- to output text to the terminal in yellow:
846
+ This uses an [ANSI escape code](https://en.wikipedia.org/wiki/ANSI_escape_code) to output text to the terminal in yellow:
947
847
 
948
- ```
848
+ ```bash
949
849
  ➜ ~  cowsay hello | rexe -me "print %Q{\u001b[33m}; puts to_a"
950
850
  ➜ ~  # or
951
851
  ➜ ~  cowsay hello | rexe -mb "print %Q{\u001b[33m}; puts self"
952
852
  ➜ ~  # or
953
853
  ➜ ~  cowsay hello | rexe "print %Q{\u001b[33m}; puts STDIN.read"
854
+ ```
855
+ ```
954
856
  _______
955
857
  < hello >
956
858
  -------
@@ -966,13 +868,11 @@ to output text to the terminal in yellow:
966
868
 
967
869
  #### More YouTube: Differentiating Success and Failure
968
870
 
969
- Let's take the YouTube example from the "Loading Files" section further.
970
- Let's have the video that loads be different for the success or failure
971
- of the command.
871
+ Let's take the YouTube example from the "Loading Files" section further. Let's have the video that loads be different for the success or failure of the command.
972
872
 
973
873
  If we put this in a load file (such as ~/.rexerc):
974
874
 
975
- ```
875
+ ```ruby
976
876
  def play(piece_code)
977
877
  pieces = {
978
878
  hallelujah: "https://www.youtube.com/watch?v=IUZEtVbJT5c&t=0m20s",
@@ -994,19 +894,17 @@ end
994
894
  def play_result_by_exit_code
995
895
  play_result(STDIN.read.chomp == '0')
996
896
  end
997
-
998
897
  ```
999
898
 
1000
899
  Then when we issue a command that succeeds, the Hallelujah Chorus is played [see footnote ^2]:
1001
900
 
1002
- ```
901
+ ```bash
1003
902
  ➜ ~  uname; echo $? | rexe play_result_by_exit_code
1004
903
  ```
1005
904
 
1006
- ...but when the command fails, in this case, with an executable which is not found, it plays Rick Astley's
1007
- "Never Gonna Give You Up":
905
+ ...but when the command fails, in this case, with an executable which is not found, it plays Rick Astley's "Never Gonna Give You Up":
1008
906
 
1009
- ```
907
+ ```bash
1010
908
  ➜ ~  uuuuu; echo $? | rexe play_result_by_exit_code
1011
909
  ```
1012
910
 
@@ -1016,7 +914,7 @@ Then when we issue a command that succeeds, the Hallelujah Chorus is played [see
1016
914
 
1017
915
  Another formatting example...I wanted to reformat this source code...
1018
916
 
1019
- ```
917
+ ```ruby
1020
918
  'i' => Inspect
1021
919
  'j' => JSON
1022
920
  'J' => Pretty JSON
@@ -1026,12 +924,9 @@ Another formatting example...I wanted to reformat this source code...
1026
924
  'y' => YAML
1027
925
  ```
1028
926
 
1029
- ...into something more suitable for my help text.
1030
- Admittedly, the time it took to do this with rexe probably exceeded the time to do it manually,
1031
- but it was an interesting exercise and made it easy to try different formats. Here it is, after
1032
- copying the original text to the clipboard:
927
+ ...into something more suitable for my help text. Admittedly, the time it took to do this with rexe probably exceeded the time to do it manually, but it was an interesting exercise and made it easy to try different formats. Here it is, after copying the original text to the clipboard:
1033
928
 
1034
- ```
929
+ ```bash
1035
930
  ➜ ~  pbpaste | rexe -ml -op "sub(%q{'}, '-o').sub(%q{' =>}, %q{ })"
1036
931
  -oi Inspect
1037
932
  -oj JSON
@@ -1047,10 +942,9 @@ copying the original text to the clipboard:
1047
942
 
1048
943
  #### Currency Conversion
1049
944
 
1050
- I travel a lot, and when I visit a country for the first time I often get confused by the exchange rate.
1051
- I put this in my `~/.rexerc`:
945
+ I travel a lot, and when I visit a country for the first time I often get confused by the exchange rate. I put this in my `~/.rexerc`:
1052
946
 
1053
- ```
947
+ ```ruby
1054
948
  # Conversion rate to US Dollars
1055
949
  module Curr
1056
950
  module_function
@@ -1061,10 +955,9 @@ module Curr
1061
955
  end
1062
956
  ```
1063
957
 
1064
- If I'm lucky enough to be at my computer when I need to do a conversion,
1065
- for example, to find the value of 150 Malaysian ringits in US dollars, I can do this:
958
+ If I'm lucky enough to be at my computer when I need to do a conversion, for example, to find the value of 150 Malaysian ringits in US dollars, I can do this:
1066
959
 
1067
- ```
960
+ ```bash
1068
961
  ➜ rexe git:(master) ✗  rexe puts 150 / Curr.myr
1069
962
  36.76470588235294
1070
963
  ```
@@ -1076,10 +969,9 @@ Obviously rates will change over time, but this will give me a general idea, whi
1076
969
 
1077
970
  #### Reformatting Grep Output
1078
971
 
1079
- I was recently asked to provide a schema for the data in my `rock_books` accounting gem. `rock_books` data is intended to be very small in size, and no data base is used. Instead, the input data is parsed on every run, and reports generated on demand. However, there are data structures (actually class instances) in memory at runtime, and their classes inherit from `Struct`.
1080
- The definition lines look like this one:
972
+ I was recently asked to provide a schema for the data in my `rock_books` accounting gem. `rock_books` data is intended to be very small in size, and no data base is used. Instead, the input data is parsed on every run, and reports generated on demand. However, there are data structures (actually class instances) in memory at runtime, and their classes inherit from `Struct`. The definition lines look like this one:
1081
973
 
1082
- ```
974
+ ```ruby
1083
975
  class JournalEntry < Struct.new(:date, :acct_amounts, :doc_short_name, :description, :receipts)
1084
976
  ```
1085
977
 
@@ -1091,7 +983,7 @@ lib/rock_books/documents/journal_entry.rb:
1091
983
 
1092
984
  So this is what worked well for me:
1093
985
 
1094
- ```
986
+ ```bash
1095
987
  ➜ ~  grep Struct **/*.rb | grep -v OpenStruct | rexe -ml -op \
1096
988
  "a = \
1097
989
  gsub('lib/rock_books/', '') \
@@ -1118,9 +1010,7 @@ types/acct_amount.rb class AcctAmount (:date, :code, :amount
1118
1010
  types/journal_entry_context.rb class JournalEntryContext (:journal, :linenum, :line)
1119
1011
  ```
1120
1012
 
1121
- Although there's a lot going on in this code,
1122
- the vertical and horizontal alignments and spacing make the code
1123
- straightforward to follow. Here's what it does:
1013
+ Although there's a lot going on in this code, the vertical and horizontal alignments and spacing make the code straightforward to follow. Here's what it does:
1124
1014
 
1125
1015
  * grep the code base for `"Struct"`
1126
1016
  * exclude references to `"OpenStruct"` with `grep -v`
@@ -1134,44 +1024,23 @@ straightforward to follow. Here's what it does:
1134
1024
 
1135
1025
  ### Conclusion
1136
1026
 
1137
- Rexe is not revolutionary technology, it's just plumbing that removes parsing,
1138
- formatting, and low level
1139
- configuration from your command line so that you can focus on the high level
1140
- task at hand.
1027
+ Rexe is not revolutionary technology, it's just plumbing that removes parsing, formatting, and low level configuration from your command line so that you can focus on the high level task at hand.
1141
1028
 
1142
- When we consider a new piece of software, we usually think "what would this be
1143
- helpful with now?". However, for me, the power of rexe is not so much what I can do
1144
- with it in a single use case now, but rather what will I be able to do over time
1145
- as I accumulate more experience and expertise with it.
1029
+ When we consider a new piece of software, we usually think "what would this be helpful with now?". However, for me, the power of rexe is not so much what I can do with it in a single use case now, but rather what will I be able to do over time as I accumulate more experience and expertise with it.
1146
1030
 
1147
- I suggest starting to use rexe even for modest improvements in workflow, even
1148
- if it doesn't seem compelling. There's a good chance that as you use it over
1149
- time, new ideas will come to you and the workflow improvements will increase
1150
- exponentially.
1031
+ I suggest starting to use rexe even for modest improvements in workflow, even if it doesn't seem compelling. There's a good chance that as you use it over time, new ideas will come to you and the workflow improvements will increase exponentially.
1151
1032
 
1152
- A word of caution though --
1153
- the complexity and difficulty of _sharing_ your rexe scripts across systems
1154
- will be proportional to the extent to which you use environment variables
1155
- and loaded files for configuration and shared code.
1156
- Be responsible and disciplined in making this configuration and code as clean and organized as possible.
1033
+ A word of caution though -- the complexity and difficulty of _sharing_ your rexe scripts across systems will be proportional to the extent to which you use environment variables and loaded files for configuration and shared code. Be responsible and disciplined in making this configuration and code as clean and organized as possible.
1157
1034
 
1158
1035
  ----
1159
1036
 
1160
1037
  #### Footnotes
1161
1038
 
1162
- [^1]: Rexe is an embellishment of the minimal but excellent `rb` script at
1163
- https://github.com/thisredone/rb. I started using `rb` and thought of lots of
1164
- other features I would like to have, so I started working on rexe.
1039
+ [1]: Rexe is an embellishment of the minimal but excellent `rb` script at https://github.com/thisredone/rb. I started using `rb` and thought of lots of other features I would like to have, so I started working on rexe.
1165
1040
 
1166
- [^2]: It's possible that when this page opens in your browser it will not play automatically.
1167
- You may need to change your default browser, or change the code that opens the URL.
1168
- Firefox's new (as of March 2019) version 66 suppresses autoplay; you can register
1169
- exceptions to this policy: open Firefox Preferences, search for "autoplay" and add
1170
- "https://www.youtube.com".
1041
+ [2]: It's possible that when this page opens in your browser it will not play automatically. You may need to change your default browser, or change the code that opens the URL. Firefox's new (as of March 2019) version 66 suppresses autoplay; you can register exceptions to this policy: open Firefox Preferences, search for "autoplay" and add "https://www.youtube.com".
1171
1042
 
1172
- [^3]: Making this truly OS-portable is a lot more complex than it looks on the surface.
1173
- On Linux, `xdg-open` may not be installed by default. Also, Windows Subsystem for Linux (WSL)
1174
- out of the box is not able to launch graphical applications.
1043
+ [3]: Making this truly OS-portable is a lot more complex than it looks on the surface. On Linux, `xdg-open` may not be installed by default. Also, Windows Subsystem for Linux (WSL) out of the box is not able to launch graphical applications.
1175
1044
 
1176
1045
  Here is a _start_ at a method that opens a resource portably across operating systems:
1177
1046
 
@@ -1190,4 +1059,4 @@ Here is a _start_ at a method that opens a resource portably across operating sy
1190
1059
  end
1191
1060
  ```
1192
1061
 
1193
- [^4]: It is an interesting quirk of the Ruby language that `ENV.to_s` returns `"ENV"` and not the contents of the `ENV` object. As a result, many of the other output formats will also return some form of `"ENV"`. You can handle this by specifying `ENV.to_h`.
1062
+ [4]: It is an interesting quirk of the Ruby language that `ENV.to_s` returns `"ENV"` and not the contents of the `ENV` object. As a result, many of the other output formats will also return some form of `"ENV"`. You can handle this by specifying `ENV.to_h`.