irb_hacks 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/MIT-LICENSE +20 -0
- data/README.html +176 -0
- data/README.md +164 -134
- data/Rakefile +54 -0
- data/VERSION.yml +3 -2
- data/irb_hacks.gemspec +18 -14
- data/lib/irb_hacks/core_ext/kernel/a_and_ae.rb +18 -11
- data/lib/irb_hacks/core_ext/kernel/less.rb +15 -8
- data/lib/irb_hacks/snippet.rb +10 -3
- data/lib/irb_hacks.rb +10 -0
- metadata +20 -7
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Alex Fortuna
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.html
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
<head>
|
2
|
+
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
|
3
|
+
<link href="dev/github.css" rel="stylesheet" type="text/css" />
|
4
|
+
</head>
|
5
|
+
<h1 id="yet-another-set-of-irb-hacks">Yet Another Set of IRB Hacks</h1>
|
6
|
+
|
7
|
+
<h2 id="setup">Setup</h2>
|
8
|
+
|
9
|
+
<pre><code>$ gem sources --add http://rubygems.org
|
10
|
+
$ gem install irb_hacks
|
11
|
+
</code></pre>
|
12
|
+
|
13
|
+
<p>Add to your <code>~/.irbrc</code>:</p>
|
14
|
+
|
15
|
+
<pre><code>require "rubygems"
|
16
|
+
require "irb_hacks"
|
17
|
+
</code></pre>
|
18
|
+
|
19
|
+
<p>Now fire up IRB for a quick test:</p>
|
20
|
+
|
21
|
+
<pre><code>$ irb
|
22
|
+
irb> ae
|
23
|
+
(snippet)>>
|
24
|
+
</code></pre>
|
25
|
+
|
26
|
+
<p>If you see “(snippet)”, you’re ready to go.</p>
|
27
|
+
|
28
|
+
<h2 id="the-hacks">The Hacks</h2>
|
29
|
+
|
30
|
+
<h3 id="code-snippets----a-and-ae">Code snippets – <code>a</code> and <code>ae</code></h3>
|
31
|
+
|
32
|
+
<p>There’s often a need to invoke our work-in-progress code a number of times using the same arguments, wrapping block, etc. For that, “code snippets” feature is quite handy.</p>
|
33
|
+
|
34
|
+
<p><code>irb_hacks</code> gem provides the two methods with short, meaningless (and thus conflict-free) names – <code>a</code> and <code>ae</code>. <code>a</code> means nothing, it’s just the first letter of the alphabet. <code>a</code> <strong>invokes</strong> the last-edited snippet. <code>ae</code> <strong>lets you edit</strong> the actual snippet (it roughly stands for “a” + “edit”).</p>
|
35
|
+
|
36
|
+
<p>A very basic example:</p>
|
37
|
+
|
38
|
+
<pre><code>irb> ae
|
39
|
+
(snippet)>> puts "Hello, world"
|
40
|
+
irb> a
|
41
|
+
Hello, world
|
42
|
+
</code></pre>
|
43
|
+
|
44
|
+
<p>Snippet arguments are supported. It’s an array called <code>args</code> in snippet context.</p>
|
45
|
+
|
46
|
+
<pre><code>irb> ae
|
47
|
+
(snippet)>> p "args", args
|
48
|
+
irb> a 10, 1.0, "a string"
|
49
|
+
"args"
|
50
|
+
[10, 1.0, "a string"]
|
51
|
+
</code></pre>
|
52
|
+
|
53
|
+
<p>Snippets work just like normal Ruby methods – they return the value of the last statement executed.</p>
|
54
|
+
|
55
|
+
<pre><code>irb> ae
|
56
|
+
(snippet)>> ["alfa", "zulu", "bravo"] + args
|
57
|
+
irb> puts a("charlie").sort
|
58
|
+
alfa
|
59
|
+
bravo
|
60
|
+
charlie
|
61
|
+
zulu
|
62
|
+
</code></pre>
|
63
|
+
|
64
|
+
<p>Snippets support code blocks. It’s a <code>Proc</code> called <code>block</code> in snippet context. Usage example follows (suppose you’re building a simplistic <code>/etc/passwd</code> parser).</p>
|
65
|
+
|
66
|
+
<pre><code>irb> ae
|
67
|
+
(snippet)>> File.readlines("/etc/passwd").map(&block).each {|s| p s}; nil
|
68
|
+
irb> a {|s| ar = s.split(":"); {:name => ar[0], :uid => ar[2]}}
|
69
|
+
{:uid=>"0", :name=>"root"}
|
70
|
+
{:uid=>"1", :name=>"bin"}
|
71
|
+
{:uid=>"2", :name=>"daemon"}
|
72
|
+
{:uid=>"3", :name=>"adm"}
|
73
|
+
...
|
74
|
+
</code></pre>
|
75
|
+
|
76
|
+
<p>Snippets are <strong>persistent</strong> though IRB invocations. That’s quite handy, since not all stuff can be dynamically reloaded and sometimes one has to restart IRB to ensure a clean reload.</p>
|
77
|
+
|
78
|
+
<pre><code>irb> ae
|
79
|
+
(snippet)>> puts "Snippets are persistent!"
|
80
|
+
irb> exit
|
81
|
+
$ irb
|
82
|
+
irb> a
|
83
|
+
Snippets are persistent!
|
84
|
+
</code></pre>
|
85
|
+
|
86
|
+
<p>Just in case, snippet history file is called <code>.irb_snippet_history</code> in your <code>$HOME</code>.</p>
|
87
|
+
|
88
|
+
<p>Snippets maintain <strong>their own</strong> Readline history. When you press [Up] and [Down] keys in <code>ae</code>, you browse the previously used snippets, not just your previous IRB input. Don’t retype the snippet you used yesterday – press [Up] a couple times and you’ll see it.</p>
|
89
|
+
|
90
|
+
<pre><code>irb> ae
|
91
|
+
(snippet)>> puts "snippet one"
|
92
|
+
irb> hala
|
93
|
+
irb> bala
|
94
|
+
irb> ae
|
95
|
+
(snippet)>> puts "snippet two"
|
96
|
+
irb> foo
|
97
|
+
irb> moo
|
98
|
+
irb> ae
|
99
|
+
(snippet)>>
|
100
|
+
# Pressing [Up] will give you...
|
101
|
+
(snippet)>> puts "snippet two"
|
102
|
+
# Pressing [Up] again will give you...
|
103
|
+
(snippet)>> puts "snippet one"
|
104
|
+
</code></pre>
|
105
|
+
|
106
|
+
<h3 id="browse-program-data-with-gnu-less">Browse program data with GNU <code>less</code></h3>
|
107
|
+
|
108
|
+
<p>Sometimes the data your code works with is too long to fit in a console window. The clearest example of this are variables filled with text content, e.g. <a href="http://github.com/whymirror/hpricot">Hpricot</a> documents/elements.</p>
|
109
|
+
|
110
|
+
<p>To solve that, the greatest paging program of all times, GNU <code>less</code>, comes to the rescue.</p>
|
111
|
+
|
112
|
+
<pre><code>$ irb
|
113
|
+
irb> files = Dir["/etc/*"].sort
|
114
|
+
# Some bulky array...
|
115
|
+
irb> less files
|
116
|
+
# ... which you browse interactively!
|
117
|
+
</code></pre>
|
118
|
+
|
119
|
+
<p>In block form, <code>less</code> hack intercepts everything output to <code>STDOUT</code> (and, optionally, to <code>STDERR</code>), and feeds it to the pager.</p>
|
120
|
+
|
121
|
+
<pre><code>$ irb
|
122
|
+
irb> less do
|
123
|
+
puts "Hello, world"
|
124
|
+
end
|
125
|
+
</code></pre>
|
126
|
+
|
127
|
+
<p>Now with <code>STDERR</code> capture:</p>
|
128
|
+
|
129
|
+
<pre><code>$ irb
|
130
|
+
irb> less(:stderr) do
|
131
|
+
puts "to stdout"
|
132
|
+
STDERR.puts "to stderr"
|
133
|
+
end
|
134
|
+
</code></pre>
|
135
|
+
|
136
|
+
<p>To specify another paging program or tweak <code>less</code> options, write in your <code>~/.irbrc</code>:</p>
|
137
|
+
|
138
|
+
<pre><code>IrbHacks.less_cmd = "more"
|
139
|
+
</code></pre>
|
140
|
+
|
141
|
+
<p>, or something else you find appropriate.</p>
|
142
|
+
|
143
|
+
<h3 id="break-execution-and-return-instant-value">Break execution and return instant value</h3>
|
144
|
+
|
145
|
+
<p>By using <code>IrbHacks.break(value)</code> you break snippet execution and make it return <code>value</code>. This is a simple yet powerful debugging technique.</p>
|
146
|
+
|
147
|
+
<p>Suppose you’re debugging the code which contains something like:</p>
|
148
|
+
|
149
|
+
<pre><code>csv.each_with_index do |fc_row, i|
|
150
|
+
row = OpenHash[*fc_row.map {|k, v| [(k.to_sym rescue k), (v.to_s.strip rescue v)]}.flatten(1)]
|
151
|
+
...
|
152
|
+
</code></pre>
|
153
|
+
|
154
|
+
<p>There’s something wrong with the code and you want to see if <code>row</code> is given the correct value. To do it, use <code>IrbHacks.break</code>:</p>
|
155
|
+
|
156
|
+
<pre><code>csv.each_with_index do |fc_row, i|
|
157
|
+
row = OpenHash[*fc_row.map {|k, v| [(k.to_sym rescue k), (v.to_s.strip rescue v)]}.flatten(1)]
|
158
|
+
IrbHacks.break(row)
|
159
|
+
</code></pre>
|
160
|
+
|
161
|
+
<p>Now all you have to do is write an <code>ae</code> snippet and call it. <code>row</code> value will be available in IRB for inspection:</p>
|
162
|
+
|
163
|
+
<pre><code>irb> ae
|
164
|
+
(snippet)>> Klass.new.method(args)
|
165
|
+
irb> row = a
|
166
|
+
# Back in IRB. Do whatever you want with `row` value now.
|
167
|
+
irb>
|
168
|
+
</code></pre>
|
169
|
+
|
170
|
+
<p>Each <code>IrbHacks.break</code> call raises an <code>IrbHacks::BreakException</code>. If you see them popping out during runtime, find the appropriate <code>IrbHacks.break</code> calls and defuse them.</p>
|
171
|
+
|
172
|
+
<h2 id="feedback">Feedback</h2>
|
173
|
+
|
174
|
+
<p>Send bug reports, suggestions and criticisms through <a href="http://github.com/dadooda/irb_hacks">project’s page on GitHub</a>.</p>
|
175
|
+
|
176
|
+
<p>Licensed under the MIT License.</p>
|
data/README.md
CHANGED
@@ -1,134 +1,164 @@
|
|
1
|
-
Yet
|
2
|
-
============================
|
3
|
-
|
4
|
-
Setup
|
5
|
-
-----
|
6
|
-
|
7
|
-
$ gem sources --add http://
|
8
|
-
$ gem install irb_hacks
|
9
|
-
|
10
|
-
Add to your `~/.irbrc`:
|
11
|
-
|
12
|
-
require "rubygems"
|
13
|
-
require "irb_hacks"
|
14
|
-
|
15
|
-
Now fire up IRB for a quick test:
|
16
|
-
|
17
|
-
$ irb
|
18
|
-
irb> ae
|
19
|
-
(snippet)>>
|
20
|
-
|
21
|
-
If you see "(snippet)", you're ready to go.
|
22
|
-
|
23
|
-
|
24
|
-
The Hacks
|
25
|
-
---------
|
26
|
-
|
27
|
-
### Code snippets -- `a` and `ae` ###
|
28
|
-
|
29
|
-
There's often a need to invoke our work-in-progress code a number of times using the same arguments, wrapping block, etc. For that, "code snippets" feature is quite handy.
|
30
|
-
|
31
|
-
`irb_hacks` gem provides the two methods with short, meaningless (and thus conflict-free) names -- `a` and `ae`. `a` means nothing, it's just the first letter of the alphabet. `a` **invokes** the last-edited snippet. `ae` **lets you edit** the actual snippet (it roughly stands for "a" + "edit").
|
32
|
-
|
33
|
-
A very basic example:
|
34
|
-
|
35
|
-
irb> ae
|
36
|
-
(snippet)>> puts "Hello, world"
|
37
|
-
irb> a
|
38
|
-
Hello, world
|
39
|
-
|
40
|
-
Snippet arguments are supported. It's an array called `args` in snippet context.
|
41
|
-
|
42
|
-
irb> ae
|
43
|
-
(snippet)>> p "args", args
|
44
|
-
irb> a 10, 1.0, "a string"
|
45
|
-
"args"
|
46
|
-
[10, 1.0, "a string"]
|
47
|
-
|
48
|
-
Snippets work just like normal Ruby methods -- they return the value of the last statement executed.
|
49
|
-
|
50
|
-
irb> ae
|
51
|
-
(snippet)>> ["alfa", "zulu", "bravo"] + args
|
52
|
-
irb> puts a("charlie").sort
|
53
|
-
alfa
|
54
|
-
bravo
|
55
|
-
charlie
|
56
|
-
zulu
|
57
|
-
|
58
|
-
Snippets support code blocks. It's a `Proc` called `block` in snippet context. Usage example follows (suppose
|
59
|
-
|
60
|
-
irb> ae
|
61
|
-
(snippet)>> File.readlines("/etc/passwd").map(&block).each {|s| p s}; nil
|
62
|
-
irb> a {|s| ar = s.split(":"); {:name => ar[0], :uid => ar[2]}}
|
63
|
-
{:uid=>"0", :name=>"root"}
|
64
|
-
{:uid=>"1", :name=>"bin"}
|
65
|
-
{:uid=>"2", :name=>"daemon"}
|
66
|
-
{:uid=>"3", :name=>"adm"}
|
67
|
-
...
|
68
|
-
|
69
|
-
Snippets are **persistent** though IRB invocations. That's quite handy, since not all stuff can be dynamically reloaded and sometimes
|
70
|
-
|
71
|
-
irb> ae
|
72
|
-
(snippet)>> puts "Snippets are persistent!"
|
73
|
-
irb> exit
|
74
|
-
$ irb
|
75
|
-
irb> a
|
76
|
-
Snippets are persistent!
|
77
|
-
|
78
|
-
Just in case, snippet history file is called `.irb_snippet_history` in your `$HOME`.
|
79
|
-
|
80
|
-
Snippets maintain **their own**
|
81
|
-
|
82
|
-
irb> ae
|
83
|
-
(snippet)>> puts "snippet one"
|
84
|
-
irb> hala
|
85
|
-
irb> bala
|
86
|
-
irb> ae
|
87
|
-
(snippet)>> puts "snippet two"
|
88
|
-
irb> foo
|
89
|
-
irb> moo
|
90
|
-
irb> ae
|
91
|
-
(snippet)>>
|
92
|
-
|
93
|
-
(snippet)>> puts "snippet two"
|
94
|
-
|
95
|
-
(snippet)>> puts "snippet one"
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
irb
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
irb
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
irb
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
1
|
+
Yet Another Set of IRB Hacks
|
2
|
+
============================
|
3
|
+
|
4
|
+
Setup
|
5
|
+
-----
|
6
|
+
|
7
|
+
$ gem sources --add http://rubygems.org
|
8
|
+
$ gem install irb_hacks
|
9
|
+
|
10
|
+
Add to your `~/.irbrc`:
|
11
|
+
|
12
|
+
require "rubygems"
|
13
|
+
require "irb_hacks"
|
14
|
+
|
15
|
+
Now fire up IRB for a quick test:
|
16
|
+
|
17
|
+
$ irb
|
18
|
+
irb> ae
|
19
|
+
(snippet)>>
|
20
|
+
|
21
|
+
If you see "(snippet)", you're ready to go.
|
22
|
+
|
23
|
+
|
24
|
+
The Hacks
|
25
|
+
---------
|
26
|
+
|
27
|
+
### Code snippets -- `a` and `ae` ###
|
28
|
+
|
29
|
+
There's often a need to invoke our work-in-progress code a number of times using the same arguments, wrapping block, etc. For that, "code snippets" feature is quite handy.
|
30
|
+
|
31
|
+
`irb_hacks` gem provides the two methods with short, meaningless (and thus conflict-free) names -- `a` and `ae`. `a` means nothing, it's just the first letter of the alphabet. `a` **invokes** the last-edited snippet. `ae` **lets you edit** the actual snippet (it roughly stands for "a" + "edit").
|
32
|
+
|
33
|
+
A very basic example:
|
34
|
+
|
35
|
+
irb> ae
|
36
|
+
(snippet)>> puts "Hello, world"
|
37
|
+
irb> a
|
38
|
+
Hello, world
|
39
|
+
|
40
|
+
Snippet arguments are supported. It's an array called `args` in snippet context.
|
41
|
+
|
42
|
+
irb> ae
|
43
|
+
(snippet)>> p "args", args
|
44
|
+
irb> a 10, 1.0, "a string"
|
45
|
+
"args"
|
46
|
+
[10, 1.0, "a string"]
|
47
|
+
|
48
|
+
Snippets work just like normal Ruby methods -- they return the value of the last statement executed.
|
49
|
+
|
50
|
+
irb> ae
|
51
|
+
(snippet)>> ["alfa", "zulu", "bravo"] + args
|
52
|
+
irb> puts a("charlie").sort
|
53
|
+
alfa
|
54
|
+
bravo
|
55
|
+
charlie
|
56
|
+
zulu
|
57
|
+
|
58
|
+
Snippets support code blocks. It's a `Proc` called `block` in snippet context. Usage example follows (suppose you're building a simplistic `/etc/passwd` parser).
|
59
|
+
|
60
|
+
irb> ae
|
61
|
+
(snippet)>> File.readlines("/etc/passwd").map(&block).each {|s| p s}; nil
|
62
|
+
irb> a {|s| ar = s.split(":"); {:name => ar[0], :uid => ar[2]}}
|
63
|
+
{:uid=>"0", :name=>"root"}
|
64
|
+
{:uid=>"1", :name=>"bin"}
|
65
|
+
{:uid=>"2", :name=>"daemon"}
|
66
|
+
{:uid=>"3", :name=>"adm"}
|
67
|
+
...
|
68
|
+
|
69
|
+
Snippets are **persistent** though IRB invocations. That's quite handy, since not all stuff can be dynamically reloaded and sometimes one has to restart IRB to ensure a clean reload.
|
70
|
+
|
71
|
+
irb> ae
|
72
|
+
(snippet)>> puts "Snippets are persistent!"
|
73
|
+
irb> exit
|
74
|
+
$ irb
|
75
|
+
irb> a
|
76
|
+
Snippets are persistent!
|
77
|
+
|
78
|
+
Just in case, snippet history file is called `.irb_snippet_history` in your `$HOME`.
|
79
|
+
|
80
|
+
Snippets maintain **their own** Readline history. When you press [Up] and [Down] keys in `ae`, you browse the previously used snippets, not just your previous IRB input. Don't retype the snippet you used yesterday -- press [Up] a couple times and you'll see it.
|
81
|
+
|
82
|
+
irb> ae
|
83
|
+
(snippet)>> puts "snippet one"
|
84
|
+
irb> hala
|
85
|
+
irb> bala
|
86
|
+
irb> ae
|
87
|
+
(snippet)>> puts "snippet two"
|
88
|
+
irb> foo
|
89
|
+
irb> moo
|
90
|
+
irb> ae
|
91
|
+
(snippet)>>
|
92
|
+
# Pressing [Up] will give you...
|
93
|
+
(snippet)>> puts "snippet two"
|
94
|
+
# Pressing [Up] again will give you...
|
95
|
+
(snippet)>> puts "snippet one"
|
96
|
+
|
97
|
+
|
98
|
+
### Browse program data with GNU `less` ###
|
99
|
+
|
100
|
+
Sometimes the data your code works with is too long to fit in a console window. The clearest example of this are variables filled with text content, e.g. [Hpricot](http://github.com/whymirror/hpricot) documents/elements.
|
101
|
+
|
102
|
+
To solve that, the greatest paging program of all times, GNU `less`, comes to the rescue.
|
103
|
+
|
104
|
+
$ irb
|
105
|
+
irb> files = Dir["/etc/*"].sort
|
106
|
+
# Some bulky array...
|
107
|
+
irb> less files
|
108
|
+
# ... which you browse interactively!
|
109
|
+
|
110
|
+
In block form, `less` hack intercepts everything output to `STDOUT` (and, optionally, to `STDERR`), and feeds it to the pager.
|
111
|
+
|
112
|
+
$ irb
|
113
|
+
irb> less do
|
114
|
+
puts "Hello, world"
|
115
|
+
end
|
116
|
+
|
117
|
+
Now with `STDERR` capture:
|
118
|
+
|
119
|
+
$ irb
|
120
|
+
irb> less(:stderr) do
|
121
|
+
puts "to stdout"
|
122
|
+
STDERR.puts "to stderr"
|
123
|
+
end
|
124
|
+
|
125
|
+
To specify another paging program or tweak `less` options, write in your `~/.irbrc`:
|
126
|
+
|
127
|
+
IrbHacks.less_cmd = "more"
|
128
|
+
|
129
|
+
, or something else you find appropriate.
|
130
|
+
|
131
|
+
|
132
|
+
### Break execution and return instant value ###
|
133
|
+
|
134
|
+
By using `IrbHacks.break(value)` you break snippet execution and make it return `value`. This is a simple yet powerful debugging technique.
|
135
|
+
|
136
|
+
Suppose you're debugging the code which contains something like:
|
137
|
+
|
138
|
+
csv.each_with_index do |fc_row, i|
|
139
|
+
row = OpenHash[*fc_row.map {|k, v| [(k.to_sym rescue k), (v.to_s.strip rescue v)]}.flatten(1)]
|
140
|
+
...
|
141
|
+
|
142
|
+
There's something wrong with the code and you want to see if `row` is given the correct value. To do it, use `IrbHacks.break`:
|
143
|
+
|
144
|
+
csv.each_with_index do |fc_row, i|
|
145
|
+
row = OpenHash[*fc_row.map {|k, v| [(k.to_sym rescue k), (v.to_s.strip rescue v)]}.flatten(1)]
|
146
|
+
IrbHacks.break(row)
|
147
|
+
|
148
|
+
Now all you have to do is write an `ae` snippet and call it. `row` value will be available in IRB for inspection:
|
149
|
+
|
150
|
+
irb> ae
|
151
|
+
(snippet)>> Klass.new.method(args)
|
152
|
+
irb> row = a
|
153
|
+
# Back in IRB. Do whatever you want with `row` value now.
|
154
|
+
irb>
|
155
|
+
|
156
|
+
Each `IrbHacks.break` call raises an `IrbHacks::BreakException`. If you see them popping out during runtime, find the appropriate `IrbHacks.break` calls and defuse them.
|
157
|
+
|
158
|
+
|
159
|
+
Feedback
|
160
|
+
--------
|
161
|
+
|
162
|
+
Send bug reports, suggestions and criticisms through [project's page on GitHub](http://github.com/dadooda/irb_hacks).
|
163
|
+
|
164
|
+
Licensed under the MIT License.
|
data/Rakefile
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require "yaml"
|
2
|
+
#require 'rake/gempackagetask'
|
3
|
+
|
4
|
+
GEM_NAME = "irb_hacks"
|
5
|
+
|
6
|
+
begin
|
7
|
+
require "jeweler"
|
8
|
+
Jeweler::Tasks.new do |gem|
|
9
|
+
gem.name = GEM_NAME
|
10
|
+
gem.summary = "Yet another set of IRB hacks"
|
11
|
+
gem.description = "Yet another set of IRB hacks"
|
12
|
+
gem.email = "alex.r@askit.org"
|
13
|
+
gem.homepage = "http://github.com/dadooda/irb_hacks"
|
14
|
+
gem.authors = ["Alex Fortuna"]
|
15
|
+
gem.files = FileList[
|
16
|
+
"[A-Z]*",
|
17
|
+
"*.gemspec",
|
18
|
+
"lib/**/*.rb",
|
19
|
+
]
|
20
|
+
end
|
21
|
+
rescue LoadError
|
22
|
+
STDERR.puts "This gem requires Jeweler to be built"
|
23
|
+
end
|
24
|
+
|
25
|
+
desc "Rebuild gemspec and package"
|
26
|
+
task :rebuild => [:gemspec, :build]
|
27
|
+
|
28
|
+
desc "Push (publish) gem to Gemcutter"
|
29
|
+
task :push do
|
30
|
+
# Yet found no way to ask Jeweler forge a complete version string for us.
|
31
|
+
vh = YAML.load(File.read("VERSION.yml"))
|
32
|
+
version = [vh[:major], vh[:minor], vh[:patch]].join(".")
|
33
|
+
pkgfile = File.join("pkg", [GEM_NAME, "-", version, ".gem"].to_s)
|
34
|
+
Kernel.system("gem", "push", pkgfile)
|
35
|
+
end
|
36
|
+
|
37
|
+
#Rake::GemPackageTask.new(spec) do |p|
|
38
|
+
# p.need_tar = true if RUBY_PLATFORM !~ /mswin/
|
39
|
+
#end
|
40
|
+
|
41
|
+
desc "Compile README preview"
|
42
|
+
task :readme do
|
43
|
+
require "kramdown"
|
44
|
+
|
45
|
+
doc = Kramdown::Document.new(File.read "README.md")
|
46
|
+
|
47
|
+
fn = "README.html"
|
48
|
+
puts "Writing '#{fn}'..."
|
49
|
+
File.open(fn, "w") do |f|
|
50
|
+
f.write(File.read "dev/head.html")
|
51
|
+
f.write(doc.to_html)
|
52
|
+
end
|
53
|
+
puts ": ok"
|
54
|
+
end
|
data/VERSION.yml
CHANGED
data/irb_hacks.gemspec
CHANGED
@@ -1,43 +1,47 @@
|
|
1
1
|
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{irb_hacks}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Alex Fortuna"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-12-13}
|
13
13
|
s.description = %q{Yet another set of IRB hacks}
|
14
14
|
s.email = %q{alex.r@askit.org}
|
15
15
|
s.extra_rdoc_files = [
|
16
|
+
"README.html",
|
16
17
|
"README.md"
|
17
18
|
]
|
18
19
|
s.files = [
|
19
20
|
"CHANGELOG.md",
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
21
|
+
"MIT-LICENSE",
|
22
|
+
"README.html",
|
23
|
+
"README.md",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION.yml",
|
26
|
+
"irb_hacks.gemspec",
|
27
|
+
"lib/irb_hacks.rb",
|
28
|
+
"lib/irb_hacks/core_ext/kernel/a_and_ae.rb",
|
29
|
+
"lib/irb_hacks/core_ext/kernel/less.rb",
|
30
|
+
"lib/irb_hacks/snippet.rb"
|
27
31
|
]
|
28
32
|
s.homepage = %q{http://github.com/dadooda/irb_hacks}
|
29
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
30
33
|
s.require_paths = ["lib"]
|
31
|
-
s.rubygems_version = %q{1.3.
|
34
|
+
s.rubygems_version = %q{1.3.7}
|
32
35
|
s.summary = %q{Yet another set of IRB hacks}
|
33
36
|
|
34
37
|
if s.respond_to? :specification_version then
|
35
38
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
36
39
|
s.specification_version = 3
|
37
40
|
|
38
|
-
if Gem::Version.new(Gem::
|
41
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
39
42
|
else
|
40
43
|
end
|
41
44
|
else
|
42
45
|
end
|
43
46
|
end
|
47
|
+
|
@@ -13,21 +13,28 @@ module IrbHacks #:nodoc:
|
|
13
13
|
def ae(*args)
|
14
14
|
IrbHacks::Snippet.edit(*args)
|
15
15
|
end
|
16
|
-
end
|
16
|
+
end # SingletonMethods
|
17
|
+
|
18
|
+
module InstanceMethods
|
19
|
+
private
|
17
20
|
|
18
|
-
|
21
|
+
def a(*args, &block)
|
22
|
+
::Kernel.a(*args, &block)
|
23
|
+
end
|
24
|
+
|
25
|
+
def ae(*args)
|
26
|
+
::Kernel.ae(*args)
|
27
|
+
end
|
28
|
+
end
|
19
29
|
end
|
20
30
|
end
|
21
31
|
end
|
22
32
|
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
def a(*args, &block)
|
27
|
-
::Kernel.a(*args, &block)
|
28
|
-
end
|
33
|
+
Kernel.extend IrbHacks::CoreExtensions::Kernel::SingletonMethods
|
29
34
|
|
30
|
-
|
31
|
-
|
32
|
-
end
|
35
|
+
module Kernel #:nodoc:
|
36
|
+
include IrbHacks::CoreExtensions::Kernel::InstanceMethods
|
33
37
|
end
|
38
|
+
|
39
|
+
# Reinclude module into those using it.
|
40
|
+
ObjectSpace.each_object(Module) {|m| (m.class_eval {include Kernel} if m.include? Kernel) rescue nil}
|
@@ -31,7 +31,7 @@ module IrbHacks #:nodoc:
|
|
31
31
|
# Non-block invocation.
|
32
32
|
if args.size < 1
|
33
33
|
# We're interactive anyway. Why not give user a quick prompt?
|
34
|
-
STDERR.puts "Nothing to show. Invoke as less(args) or less(options, &block)
|
34
|
+
STDERR.puts "Nothing to show. Invoke as less(args) or less(options, &block)"
|
35
35
|
else
|
36
36
|
File.popen(less_cmd, "w") do |f|
|
37
37
|
f.puts args
|
@@ -69,21 +69,28 @@ module IrbHacks #:nodoc:
|
|
69
69
|
STDOUT.reopen(old_stdout)
|
70
70
|
STDERR.reopen(old_stderr) if o_stderr
|
71
71
|
end
|
72
|
-
end # if block
|
72
|
+
end # if block
|
73
73
|
|
74
74
|
nil
|
75
75
|
end # less
|
76
76
|
end # SingletonMethods
|
77
77
|
|
78
|
-
|
78
|
+
module InstanceMethods
|
79
|
+
private
|
80
|
+
|
81
|
+
def less(*args, &block)
|
82
|
+
::Kernel.less(*args, &block)
|
83
|
+
end
|
84
|
+
end # InstanceMethods
|
79
85
|
end # Kernel
|
80
86
|
end # CoreExtensions
|
81
87
|
end
|
82
88
|
|
83
|
-
|
84
|
-
private
|
89
|
+
Kernel.extend IrbHacks::CoreExtensions::Kernel::SingletonMethods
|
85
90
|
|
86
|
-
|
87
|
-
|
88
|
-
end
|
91
|
+
module Kernel #:nodoc:
|
92
|
+
include IrbHacks::CoreExtensions::Kernel::InstanceMethods
|
89
93
|
end
|
94
|
+
|
95
|
+
# Reinclude module into those using it.
|
96
|
+
ObjectSpace.each_object(Module) {|m| (m.class_eval {include Kernel} if m.include? Kernel) rescue nil}
|
data/lib/irb_hacks/snippet.rb
CHANGED
@@ -2,8 +2,9 @@ require "readline"
|
|
2
2
|
|
3
3
|
module IrbHacks #:nodoc:
|
4
4
|
module Snippet
|
5
|
+
#TODO: Configured values. Config is common for entire IrbHacks.
|
5
6
|
HISTORY_FILE = File.join(ENV["HOME"], ".irb_snippet_history")
|
6
|
-
HISTORY_SIZE =
|
7
|
+
HISTORY_SIZE = 500
|
7
8
|
|
8
9
|
# Edit code snippet.
|
9
10
|
def self.edit
|
@@ -55,13 +56,19 @@ module IrbHacks #:nodoc:
|
|
55
56
|
nil
|
56
57
|
end
|
57
58
|
|
58
|
-
@history = [%{puts "YOUR test code here"}] if not @history
|
59
|
+
@history = [%{puts "YOUR test code here"}] if not @history
|
59
60
|
end
|
60
61
|
|
61
62
|
# Run code snippet.
|
63
|
+
# If <tt>IrbHacks.break</tt> is called anywhere, immediately return its argument.
|
62
64
|
def self.run(*args, &block)
|
63
65
|
if (code = @history.last)
|
64
|
-
|
66
|
+
begin
|
67
|
+
eval(code, &block)
|
68
|
+
rescue IrbHacks::BreakException => e
|
69
|
+
# If invoked as documented, `e.message` is always an array.
|
70
|
+
e.message[0]
|
71
|
+
end
|
65
72
|
end
|
66
73
|
end
|
67
74
|
|
data/lib/irb_hacks.rb
CHANGED
@@ -3,6 +3,14 @@ require "yaml"
|
|
3
3
|
Dir[File.join(File.dirname(__FILE__), "irb_hacks/**/*.rb")].each {|fn| require fn}
|
4
4
|
|
5
5
|
module IrbHacks
|
6
|
+
# Break execution, return value if invoked from `a`.
|
7
|
+
#
|
8
|
+
# IrbHacks.break
|
9
|
+
# IrbHacks.break("hi")
|
10
|
+
def self.break(value = nil)
|
11
|
+
raise BreakException, [value]
|
12
|
+
end
|
13
|
+
|
6
14
|
def self.less_cmd
|
7
15
|
@less_cmd
|
8
16
|
end
|
@@ -11,6 +19,8 @@ module IrbHacks
|
|
11
19
|
@less_cmd = cmd
|
12
20
|
end
|
13
21
|
|
22
|
+
class BreakException < Exception; end
|
23
|
+
|
14
24
|
#--------------------------------------- Defaults
|
15
25
|
|
16
26
|
self.less_cmd = "less -R"
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: irb_hacks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 2
|
8
|
+
- 0
|
9
|
+
version: 0.2.0
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Alex Fortuna
|
@@ -9,7 +14,7 @@ autorequire:
|
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
11
16
|
|
12
|
-
date: 2010-
|
17
|
+
date: 2010-12-13 00:00:00 +03:00
|
13
18
|
default_executable:
|
14
19
|
dependencies: []
|
15
20
|
|
@@ -20,10 +25,14 @@ executables: []
|
|
20
25
|
extensions: []
|
21
26
|
|
22
27
|
extra_rdoc_files:
|
28
|
+
- README.html
|
23
29
|
- README.md
|
24
30
|
files:
|
25
31
|
- CHANGELOG.md
|
32
|
+
- MIT-LICENSE
|
33
|
+
- README.html
|
26
34
|
- README.md
|
35
|
+
- Rakefile
|
27
36
|
- VERSION.yml
|
28
37
|
- irb_hacks.gemspec
|
29
38
|
- lib/irb_hacks.rb
|
@@ -35,26 +44,30 @@ homepage: http://github.com/dadooda/irb_hacks
|
|
35
44
|
licenses: []
|
36
45
|
|
37
46
|
post_install_message:
|
38
|
-
rdoc_options:
|
39
|
-
|
47
|
+
rdoc_options: []
|
48
|
+
|
40
49
|
require_paths:
|
41
50
|
- lib
|
42
51
|
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
43
53
|
requirements:
|
44
54
|
- - ">="
|
45
55
|
- !ruby/object:Gem::Version
|
56
|
+
segments:
|
57
|
+
- 0
|
46
58
|
version: "0"
|
47
|
-
version:
|
48
59
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
49
61
|
requirements:
|
50
62
|
- - ">="
|
51
63
|
- !ruby/object:Gem::Version
|
64
|
+
segments:
|
65
|
+
- 0
|
52
66
|
version: "0"
|
53
|
-
version:
|
54
67
|
requirements: []
|
55
68
|
|
56
69
|
rubyforge_project:
|
57
|
-
rubygems_version: 1.3.
|
70
|
+
rubygems_version: 1.3.7
|
58
71
|
signing_key:
|
59
72
|
specification_version: 3
|
60
73
|
summary: Yet another set of IRB hacks
|