irb_hacks 0.2.3 → 0.2.4
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/.gitignore +13 -0
- data/Gemfile +4 -0
- data/MIT-LICENSE +1 -1
- data/README.md +118 -87
- data/Rakefile +1 -44
- data/irb_hacks.gemspec +15 -38
- data/lib/irb_hacks/break_exception.rb +7 -1
- data/lib/irb_hacks/snippet.rb +1 -2
- data/lib/irb_hacks/version.rb +4 -0
- data/lib/irb_hacks.rb +1 -1
- metadata +57 -33
- data/VERSION.yml +0 -5
data/.gitignore
ADDED
data/Gemfile
ADDED
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,30 +1,36 @@
|
|
1
|
-
Yet
|
1
|
+
Yet another set of IRB hacks
|
2
2
|
============================
|
3
3
|
|
4
4
|
Setup
|
5
5
|
-----
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
~~~
|
8
|
+
$ gem sources --add http://rubygems.org
|
9
|
+
$ gem install irb_hacks
|
10
|
+
~~~
|
9
11
|
|
10
12
|
Add to your `~/.irbrc`:
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
+
~~~
|
15
|
+
require "rubygems"
|
16
|
+
require "irb_hacks"
|
17
|
+
~~~
|
14
18
|
|
15
19
|
Now fire up IRB for a quick test:
|
16
20
|
|
17
|
-
|
18
|
-
|
19
|
-
|
21
|
+
~~~
|
22
|
+
$ irb
|
23
|
+
irb> ae
|
24
|
+
(snippet)>>
|
25
|
+
~~~
|
20
26
|
|
21
|
-
If you see
|
27
|
+
If you see `(snippet)`, you're ready to go.
|
22
28
|
|
23
29
|
|
24
|
-
The
|
30
|
+
The hacks
|
25
31
|
---------
|
26
32
|
|
27
|
-
### Code
|
33
|
+
### Code snippets -- `a` and `ae` ###
|
28
34
|
|
29
35
|
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
36
|
|
@@ -32,124 +38,148 @@ There's often a need to invoke our work-in-progress code a number of times using
|
|
32
38
|
|
33
39
|
A very basic example:
|
34
40
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
41
|
+
~~~
|
42
|
+
irb> ae
|
43
|
+
(snippet)>> puts "Hello, world!"
|
44
|
+
irb> a
|
45
|
+
Hello, world!
|
46
|
+
~~~
|
39
47
|
|
40
48
|
Snippet arguments are supported. It's an array called `args` in snippet context.
|
41
49
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
50
|
+
~~~
|
51
|
+
irb> ae
|
52
|
+
(snippet)>> p "args", args
|
53
|
+
irb> a 10, 1.0, "a string"
|
54
|
+
"args"
|
55
|
+
[10, 1.0, "a string"]
|
56
|
+
~~~
|
47
57
|
|
48
58
|
Snippets work just like normal Ruby methods -- they return the value of the last statement executed.
|
49
59
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
60
|
+
~~~
|
61
|
+
irb> ae
|
62
|
+
(snippet)>> ["alfa", "zulu", "bravo"] + args
|
63
|
+
irb> puts a("charlie").sort
|
64
|
+
alfa
|
65
|
+
bravo
|
66
|
+
charlie
|
67
|
+
zulu
|
68
|
+
~~~
|
57
69
|
|
58
70
|
Snippets support code blocks. It's a `Proc` object called `block` in snippet context. Usage example follows. Suppose you're building a simplistic `/etc/passwd` parser. You put the actual reading in the snippet, but do line data manipulation in a block:
|
59
71
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
72
|
+
~~~
|
73
|
+
irb> ae
|
74
|
+
(snippet)>> File.readlines("/etc/passwd").map(&block).each {|s| p s}; nil
|
75
|
+
irb> a {|s| ar = s.split(":"); {:name => ar[0], :uid => ar[2]}}
|
76
|
+
{:uid=>"0", :name=>"root"}
|
77
|
+
{:uid=>"1", :name=>"bin"}
|
78
|
+
{:uid=>"2", :name=>"daemon"}
|
79
|
+
{:uid=>"3", :name=>"adm"}
|
80
|
+
...
|
81
|
+
~~~
|
68
82
|
|
69
83
|
Snippets are **persistent** thoughout IRB invocations. That's quite handy, since not all stuff can be dynamically reloaded and sometimes we have to restart IRB to ensure a clean reload.
|
70
84
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
85
|
+
~~~
|
86
|
+
irb> ae
|
87
|
+
(snippet)>> puts "Snippets are persistent!"
|
88
|
+
irb> exit
|
89
|
+
$ irb
|
90
|
+
irb> a
|
91
|
+
Snippets are persistent!
|
92
|
+
~~~
|
77
93
|
|
78
94
|
Just in case, snippet history file is called `~/.irb_snippet_history` by default.
|
79
95
|
|
80
96
|
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. So don't retype the snippet you used yesterday -- press [Up] a few times and you'll see it.
|
81
97
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
98
|
+
~~~
|
99
|
+
irb> ae
|
100
|
+
(snippet)>> puts "snippet one"
|
101
|
+
irb> hala
|
102
|
+
irb> bala
|
103
|
+
irb> ae
|
104
|
+
(snippet)>> puts "snippet two"
|
105
|
+
irb> foo
|
106
|
+
irb> moo
|
107
|
+
irb> ae
|
108
|
+
(snippet)>>
|
109
|
+
# Pressing [Up] will give you...
|
110
|
+
(snippet)>> puts "snippet two"
|
111
|
+
# Pressing [Up] again will give you...
|
112
|
+
(snippet)>> puts "snippet one"
|
113
|
+
~~~
|
96
114
|
|
97
115
|
You can configure some aspects of the snippets. Read "Configuration" chapter below.
|
98
116
|
|
99
117
|
|
100
|
-
### Browse
|
118
|
+
### Browse program data with GNU `less` ###
|
101
119
|
|
102
120
|
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.
|
103
121
|
|
104
122
|
To solve that, the greatest paging program of all times, GNU `less`, comes to the rescue.
|
105
123
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
124
|
+
~~~
|
125
|
+
$ irb
|
126
|
+
irb> files = Dir["/etc/*"].sort
|
127
|
+
# Some bulky array...
|
128
|
+
irb> less files
|
129
|
+
# ...which you browse interactively!
|
130
|
+
~~~
|
111
131
|
|
112
132
|
In block form, `less` hack intercepts everything output to `STDOUT` (and, optionally, to `STDERR`), and feeds it to the pager.
|
113
133
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
134
|
+
~~~
|
135
|
+
$ irb
|
136
|
+
irb> less do
|
137
|
+
puts "Hello, world"
|
138
|
+
end
|
139
|
+
~~~
|
118
140
|
|
119
141
|
Now with `STDERR` capture:
|
120
142
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
143
|
+
~~~
|
144
|
+
$ irb
|
145
|
+
irb> less(:stderr) do
|
146
|
+
puts "to stdout"
|
147
|
+
STDERR.puts "to stderr"
|
148
|
+
end
|
149
|
+
~~~
|
126
150
|
|
127
151
|
You can configure which pager program to use and with which options. Read "Configuration" chapter below.
|
128
152
|
|
129
153
|
|
130
|
-
### Break
|
154
|
+
### Break execution and return instant value ###
|
131
155
|
|
132
156
|
By using `IrbHacks.break(value)` you break snippet (`a`) execution and make it return `value`. This is a simple yet powerful debugging technique.
|
133
157
|
|
134
158
|
Suppose you're debugging the code which contains something like:
|
135
159
|
|
136
|
-
|
137
|
-
|
138
|
-
|
160
|
+
~~~
|
161
|
+
csv.each_with_index do |fc_row, i|
|
162
|
+
row = Hash[*fc_row.map {|k, v| [(k.to_sym rescue k), (v.to_s.strip rescue v)]}.flatten(1)]
|
163
|
+
...
|
164
|
+
~~~
|
139
165
|
|
140
166
|
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`:
|
141
167
|
|
142
|
-
|
143
|
-
|
144
|
-
|
168
|
+
~~~
|
169
|
+
csv.each_with_index do |fc_row, i|
|
170
|
+
row = Hash[*fc_row.map {|k, v| [(k.to_sym rescue k), (v.to_s.strip rescue v)]}.flatten(1)]
|
171
|
+
IrbHacks.break(row)
|
172
|
+
~~~
|
145
173
|
|
146
174
|
Now all you have to do is write an `ae` snippet and call it. `row` value will be available in IRB for inspection:
|
147
175
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
176
|
+
~~~
|
177
|
+
irb> ae
|
178
|
+
(snippet)>> Klass.new.method(args)
|
179
|
+
irb> row = a
|
180
|
+
# Back in IRB. Do whatever you want with `row` value now.
|
181
|
+
irb>
|
182
|
+
~~~
|
153
183
|
|
154
184
|
Each `IrbHacks.break` call raises an `IrbHacks::BreakException`. If you see them popping out runtime, find the appropriate `IrbHacks.break` calls and defuse them.
|
155
185
|
|
@@ -159,13 +189,14 @@ Configuration
|
|
159
189
|
|
160
190
|
Via `IrbHacks.conf` object you can configure various features of `irb_hacks`. Add `IrbHacks.conf` manipulation code to your `.irbrc`:
|
161
191
|
|
162
|
-
|
163
|
-
|
192
|
+
~~~
|
193
|
+
require "rubygems"
|
194
|
+
require "irb_hacks"
|
164
195
|
|
165
|
-
|
196
|
+
IrbHacks.conf.snippet_prompt = ">>> "
|
197
|
+
~~~
|
166
198
|
|
167
|
-
|
168
|
-
### Configuration Variables (`IrbHacks.conf.*`)###
|
199
|
+
### Configuration variables (`IrbHacks.conf.*`)###
|
169
200
|
|
170
201
|
* `less_cmd` -- System command to invoke pager for `less`.
|
171
202
|
* `snippet_history_file` -- Snippet (`a`, `ae`) history file.
|
data/Rakefile
CHANGED
@@ -1,44 +1 @@
|
|
1
|
-
require "
|
2
|
-
require "yaml"
|
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 RubyGems.org"
|
29
|
-
task :push do
|
30
|
-
# NOTE: 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], vh[:build]].compact.join(".")
|
33
|
-
pkgfile = File.join("pkg", "#{GEM_NAME}-#{version}.gem")
|
34
|
-
Kernel.system("gem", "push", pkgfile)
|
35
|
-
end
|
36
|
-
|
37
|
-
desc "Generate RDoc documentation"
|
38
|
-
Rake::RDocTask.new(:rdoc) do |rdoc|
|
39
|
-
rdoc.rdoc_dir = "doc"
|
40
|
-
rdoc.title = "IrbHacks"
|
41
|
-
#rdoc.options << "--line-numbers"
|
42
|
-
#rdoc.options << "--inline-source"
|
43
|
-
rdoc.rdoc_files.include("lib/**/*.rb")
|
44
|
-
end
|
1
|
+
require "bundler/gem_tasks"
|
data/irb_hacks.gemspec
CHANGED
@@ -1,45 +1,22 @@
|
|
1
|
-
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
-
# -*- encoding: utf-8 -*-
|
1
|
+
require File.expand_path("../lib/irb_hacks/version", __FILE__)
|
5
2
|
|
6
3
|
Gem::Specification.new do |s|
|
7
|
-
s.name =
|
8
|
-
s.version =
|
9
|
-
|
10
|
-
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
4
|
+
s.name = "irb_hacks"
|
5
|
+
s.version = IrbHacks::VERSION
|
11
6
|
s.authors = ["Alex Fortuna"]
|
12
|
-
s.
|
13
|
-
s.
|
14
|
-
|
15
|
-
s
|
16
|
-
"README.md"
|
17
|
-
]
|
18
|
-
s.files = [
|
19
|
-
"MIT-LICENSE",
|
20
|
-
"README.md",
|
21
|
-
"Rakefile",
|
22
|
-
"VERSION.yml",
|
23
|
-
"irb_hacks.gemspec",
|
24
|
-
"lib/irb_hacks.rb",
|
25
|
-
"lib/irb_hacks/break_exception.rb",
|
26
|
-
"lib/irb_hacks/config.rb",
|
27
|
-
"lib/irb_hacks/core_ext/kernel/a_and_ae.rb",
|
28
|
-
"lib/irb_hacks/core_ext/kernel/less.rb",
|
29
|
-
"lib/irb_hacks/snippet.rb"
|
30
|
-
]
|
31
|
-
s.homepage = %q{http://github.com/dadooda/irb_hacks}
|
32
|
-
s.require_paths = ["lib"]
|
33
|
-
s.rubygems_version = %q{1.6.2}
|
7
|
+
s.email = ["alex.r@askit.org"]
|
8
|
+
s.homepage = "http://github.com/dadooda/irb_hacks"
|
9
|
+
|
10
|
+
# Copy these from class's description, adjust markup.
|
34
11
|
s.summary = %q{Yet another set of IRB hacks}
|
12
|
+
s.description = %q{Yet another set of IRB hacks}
|
13
|
+
# end of s.description=
|
35
14
|
|
36
|
-
|
37
|
-
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map {|f| File.basename(f)}
|
18
|
+
s.require_paths = ["lib"]
|
38
19
|
|
39
|
-
|
40
|
-
|
41
|
-
end
|
42
|
-
else
|
43
|
-
end
|
20
|
+
s.add_development_dependency "rspec"
|
21
|
+
s.add_development_dependency "yard"
|
44
22
|
end
|
45
|
-
|
data/lib/irb_hacks/snippet.rb
CHANGED
@@ -89,8 +89,7 @@ module IrbHacks
|
|
89
89
|
# NOTE: Passing `binding` is important to provide a better backtrace when exception occurs.
|
90
90
|
eval(code, binding, &block)
|
91
91
|
rescue IrbHacks::BreakException => e
|
92
|
-
|
93
|
-
e.message[0]
|
92
|
+
return e.value
|
94
93
|
end
|
95
94
|
end
|
96
95
|
end
|
data/lib/irb_hacks.rb
CHANGED
metadata
CHANGED
@@ -1,32 +1,60 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: irb_hacks
|
3
|
-
version: !ruby/object:Gem::Version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.4
|
4
5
|
prerelease:
|
5
|
-
version: 0.2.3
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Alex Fortuna
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
date: 2012-05-01 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: yard
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
17
46
|
description: Yet another set of IRB hacks
|
18
|
-
email:
|
47
|
+
email:
|
48
|
+
- alex.r@askit.org
|
19
49
|
executables: []
|
20
|
-
|
21
50
|
extensions: []
|
22
|
-
|
23
|
-
|
24
|
-
-
|
25
|
-
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- .gitignore
|
54
|
+
- Gemfile
|
26
55
|
- MIT-LICENSE
|
27
56
|
- README.md
|
28
57
|
- Rakefile
|
29
|
-
- VERSION.yml
|
30
58
|
- irb_hacks.gemspec
|
31
59
|
- lib/irb_hacks.rb
|
32
60
|
- lib/irb_hacks/break_exception.rb
|
@@ -34,33 +62,29 @@ files:
|
|
34
62
|
- lib/irb_hacks/core_ext/kernel/a_and_ae.rb
|
35
63
|
- lib/irb_hacks/core_ext/kernel/less.rb
|
36
64
|
- lib/irb_hacks/snippet.rb
|
37
|
-
|
65
|
+
- lib/irb_hacks/version.rb
|
38
66
|
homepage: http://github.com/dadooda/irb_hacks
|
39
67
|
licenses: []
|
40
|
-
|
41
68
|
post_install_message:
|
42
69
|
rdoc_options: []
|
43
|
-
|
44
|
-
require_paths:
|
70
|
+
require_paths:
|
45
71
|
- lib
|
46
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
73
|
none: false
|
48
|
-
requirements:
|
49
|
-
- -
|
50
|
-
- !ruby/object:Gem::Version
|
51
|
-
version:
|
52
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
79
|
none: false
|
54
|
-
requirements:
|
55
|
-
- -
|
56
|
-
- !ruby/object:Gem::Version
|
57
|
-
version:
|
80
|
+
requirements:
|
81
|
+
- - ! '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
58
84
|
requirements: []
|
59
|
-
|
60
85
|
rubyforge_project:
|
61
|
-
rubygems_version: 1.
|
86
|
+
rubygems_version: 1.8.21
|
62
87
|
signing_key:
|
63
88
|
specification_version: 3
|
64
89
|
summary: Yet another set of IRB hacks
|
65
90
|
test_files: []
|
66
|
-
|