irb 1.0.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.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +6 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +55 -0
- data/Rakefile +10 -0
- data/bin/console +6 -0
- data/bin/setup +6 -0
- data/exe/irb +11 -0
- data/irb.gemspec +26 -0
- data/lib/irb.rb +798 -0
- data/lib/irb/cmd/chws.rb +34 -0
- data/lib/irb/cmd/fork.rb +39 -0
- data/lib/irb/cmd/help.rb +42 -0
- data/lib/irb/cmd/load.rb +67 -0
- data/lib/irb/cmd/nop.rb +39 -0
- data/lib/irb/cmd/pushws.rb +41 -0
- data/lib/irb/cmd/subirb.rb +43 -0
- data/lib/irb/completion.rb +244 -0
- data/lib/irb/context.rb +425 -0
- data/lib/irb/ext/change-ws.rb +46 -0
- data/lib/irb/ext/history.rb +119 -0
- data/lib/irb/ext/loader.rb +129 -0
- data/lib/irb/ext/multi-irb.rb +265 -0
- data/lib/irb/ext/save-history.rb +105 -0
- data/lib/irb/ext/tracer.rb +72 -0
- data/lib/irb/ext/use-loader.rb +74 -0
- data/lib/irb/ext/workspaces.rb +67 -0
- data/lib/irb/extend-command.rb +306 -0
- data/lib/irb/frame.rb +81 -0
- data/lib/irb/help.rb +37 -0
- data/lib/irb/init.rb +302 -0
- data/lib/irb/input-method.rb +192 -0
- data/lib/irb/inspector.rb +132 -0
- data/lib/irb/lc/.document +4 -0
- data/lib/irb/lc/error.rb +32 -0
- data/lib/irb/lc/help-message +49 -0
- data/lib/irb/lc/ja/encoding_aliases.rb +11 -0
- data/lib/irb/lc/ja/error.rb +31 -0
- data/lib/irb/lc/ja/help-message +52 -0
- data/lib/irb/locale.rb +182 -0
- data/lib/irb/magic-file.rb +38 -0
- data/lib/irb/notifier.rb +232 -0
- data/lib/irb/output-method.rb +92 -0
- data/lib/irb/ruby-lex.rb +1180 -0
- data/lib/irb/ruby-token.rb +267 -0
- data/lib/irb/slex.rb +282 -0
- data/lib/irb/src_encoding.rb +7 -0
- data/lib/irb/version.rb +17 -0
- data/lib/irb/workspace.rb +143 -0
- data/lib/irb/ws-for-case-2.rb +15 -0
- data/lib/irb/xmp.rb +170 -0
- metadata +125 -0
@@ -0,0 +1,105 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
# save-history.rb -
|
3
|
+
# $Release Version: 0.9.6$
|
4
|
+
# $Revision$
|
5
|
+
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
6
|
+
#
|
7
|
+
# --
|
8
|
+
#
|
9
|
+
#
|
10
|
+
#
|
11
|
+
|
12
|
+
require "readline"
|
13
|
+
|
14
|
+
module IRB
|
15
|
+
module HistorySavingAbility # :nodoc:
|
16
|
+
end
|
17
|
+
|
18
|
+
class Context
|
19
|
+
def init_save_history# :nodoc:
|
20
|
+
unless (class<<@io;self;end).include?(HistorySavingAbility)
|
21
|
+
@io.extend(HistorySavingAbility)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# A copy of the default <code>IRB.conf[:SAVE_HISTORY]</code>
|
26
|
+
def save_history
|
27
|
+
IRB.conf[:SAVE_HISTORY]
|
28
|
+
end
|
29
|
+
|
30
|
+
remove_method :save_history= if respond_to?(:save_history=)
|
31
|
+
# Sets <code>IRB.conf[:SAVE_HISTORY]</code> to the given +val+ and calls
|
32
|
+
# #init_save_history with this context.
|
33
|
+
#
|
34
|
+
# Will store the number of +val+ entries of history in the #history_file
|
35
|
+
#
|
36
|
+
# Add the following to your +.irbrc+ to change the number of history
|
37
|
+
# entries stored to 1000:
|
38
|
+
#
|
39
|
+
# IRB.conf[:SAVE_HISTORY] = 1000
|
40
|
+
def save_history=(val)
|
41
|
+
IRB.conf[:SAVE_HISTORY] = val
|
42
|
+
if val
|
43
|
+
main_context = IRB.conf[:MAIN_CONTEXT]
|
44
|
+
main_context = self unless main_context
|
45
|
+
main_context.init_save_history
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# A copy of the default <code>IRB.conf[:HISTORY_FILE]</code>
|
50
|
+
def history_file
|
51
|
+
IRB.conf[:HISTORY_FILE]
|
52
|
+
end
|
53
|
+
|
54
|
+
# Set <code>IRB.conf[:HISTORY_FILE]</code> to the given +hist+.
|
55
|
+
def history_file=(hist)
|
56
|
+
IRB.conf[:HISTORY_FILE] = hist
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
module HistorySavingAbility # :nodoc:
|
61
|
+
include Readline
|
62
|
+
|
63
|
+
def HistorySavingAbility.extended(obj)
|
64
|
+
IRB.conf[:AT_EXIT].push proc{obj.save_history}
|
65
|
+
obj.load_history
|
66
|
+
obj
|
67
|
+
end
|
68
|
+
|
69
|
+
def load_history
|
70
|
+
if history_file = IRB.conf[:HISTORY_FILE]
|
71
|
+
history_file = File.expand_path(history_file)
|
72
|
+
end
|
73
|
+
history_file = IRB.rc_file("_history") unless history_file
|
74
|
+
if File.exist?(history_file)
|
75
|
+
open(history_file) do |f|
|
76
|
+
f.each {|l| HISTORY << l.chomp}
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def save_history
|
82
|
+
if num = IRB.conf[:SAVE_HISTORY] and (num = num.to_i) > 0
|
83
|
+
if history_file = IRB.conf[:HISTORY_FILE]
|
84
|
+
history_file = File.expand_path(history_file)
|
85
|
+
end
|
86
|
+
history_file = IRB.rc_file("_history") unless history_file
|
87
|
+
|
88
|
+
# Change the permission of a file that already exists[BUG #7694]
|
89
|
+
begin
|
90
|
+
if File.stat(history_file).mode & 066 != 0
|
91
|
+
File.chmod(0600, history_file)
|
92
|
+
end
|
93
|
+
rescue Errno::ENOENT
|
94
|
+
rescue
|
95
|
+
raise
|
96
|
+
end
|
97
|
+
|
98
|
+
open(history_file, 'w', 0600 ) do |f|
|
99
|
+
hist = HISTORY.to_a
|
100
|
+
f.puts(hist[-num..-1] || hist)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
#
|
3
|
+
# irb/lib/tracer.rb -
|
4
|
+
# $Release Version: 0.9.6$
|
5
|
+
# $Revision$
|
6
|
+
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
7
|
+
#
|
8
|
+
# --
|
9
|
+
#
|
10
|
+
#
|
11
|
+
#
|
12
|
+
require "tracer"
|
13
|
+
|
14
|
+
module IRB
|
15
|
+
|
16
|
+
# initialize tracing function
|
17
|
+
def IRB.initialize_tracer
|
18
|
+
Tracer.verbose = false
|
19
|
+
Tracer.add_filter {
|
20
|
+
|event, file, line, id, binding, *rests|
|
21
|
+
/^#{Regexp.quote(@CONF[:IRB_LIB_PATH])}/ !~ file and
|
22
|
+
File::basename(file) != "irb.rb"
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
class Context
|
27
|
+
# Whether Tracer is used when evaluating statements in this context.
|
28
|
+
#
|
29
|
+
# See +lib/tracer.rb+ for more information.
|
30
|
+
attr_reader :use_tracer
|
31
|
+
alias use_tracer? use_tracer
|
32
|
+
|
33
|
+
# Sets whether or not to use the Tracer library when evaluating statements
|
34
|
+
# in this context.
|
35
|
+
#
|
36
|
+
# See +lib/tracer.rb+ for more information.
|
37
|
+
def use_tracer=(opt)
|
38
|
+
if opt
|
39
|
+
Tracer.set_get_line_procs(@irb_path) {
|
40
|
+
|line_no, *rests|
|
41
|
+
@io.line(line_no)
|
42
|
+
}
|
43
|
+
elsif !opt && @use_tracer
|
44
|
+
Tracer.off
|
45
|
+
end
|
46
|
+
@use_tracer=opt
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class WorkSpace
|
51
|
+
alias __evaluate__ evaluate
|
52
|
+
# Evaluate the context of this workspace and use the Tracer library to
|
53
|
+
# output the exact lines of code are being executed in chronological order.
|
54
|
+
#
|
55
|
+
# See +lib/tracer.rb+ for more information.
|
56
|
+
def evaluate(context, statements, file = nil, line = nil)
|
57
|
+
if context.use_tracer? && file != nil && line != nil
|
58
|
+
Tracer.on
|
59
|
+
begin
|
60
|
+
__evaluate__(context, statements, file, line)
|
61
|
+
ensure
|
62
|
+
Tracer.off
|
63
|
+
end
|
64
|
+
else
|
65
|
+
__evaluate__(context, statements, file || __FILE__, line || __LINE__)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
IRB.initialize_tracer
|
71
|
+
end
|
72
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
#
|
3
|
+
# use-loader.rb -
|
4
|
+
# $Release Version: 0.9.6$
|
5
|
+
# $Revision$
|
6
|
+
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
7
|
+
#
|
8
|
+
# --
|
9
|
+
#
|
10
|
+
#
|
11
|
+
#
|
12
|
+
|
13
|
+
require_relative "../cmd/load"
|
14
|
+
require_relative "loader"
|
15
|
+
|
16
|
+
class Object
|
17
|
+
alias __original__load__IRB_use_loader__ load
|
18
|
+
alias __original__require__IRB_use_loader__ require
|
19
|
+
end
|
20
|
+
|
21
|
+
module IRB
|
22
|
+
module ExtendCommandBundle
|
23
|
+
# Loads the given file similarly to Kernel#load, see IrbLoader#irb_load
|
24
|
+
def irb_load(*opts, &b)
|
25
|
+
ExtendCommand::Load.execute(irb_context, *opts, &b)
|
26
|
+
end
|
27
|
+
# Loads the given file similarly to Kernel#require
|
28
|
+
def irb_require(*opts, &b)
|
29
|
+
ExtendCommand::Require.execute(irb_context, *opts, &b)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Context
|
34
|
+
|
35
|
+
IRB.conf[:USE_LOADER] = false
|
36
|
+
|
37
|
+
# Returns whether +irb+'s own file reader method is used by
|
38
|
+
# +load+/+require+ or not.
|
39
|
+
#
|
40
|
+
# This mode is globally affected (irb-wide).
|
41
|
+
def use_loader
|
42
|
+
IRB.conf[:USE_LOADER]
|
43
|
+
end
|
44
|
+
|
45
|
+
alias use_loader? use_loader
|
46
|
+
|
47
|
+
# Sets IRB.conf[:USE_LOADER]
|
48
|
+
#
|
49
|
+
# See #use_loader for more information.
|
50
|
+
def use_loader=(opt)
|
51
|
+
|
52
|
+
if IRB.conf[:USE_LOADER] != opt
|
53
|
+
IRB.conf[:USE_LOADER] = opt
|
54
|
+
if opt
|
55
|
+
if !$".include?("irb/cmd/load")
|
56
|
+
end
|
57
|
+
(class<<@workspace.main;self;end).instance_eval {
|
58
|
+
alias_method :load, :irb_load
|
59
|
+
alias_method :require, :irb_require
|
60
|
+
}
|
61
|
+
else
|
62
|
+
(class<<@workspace.main;self;end).instance_eval {
|
63
|
+
alias_method :load, :__original__load__IRB_use_loader__
|
64
|
+
alias_method :require, :__original__require__IRB_use_loader__
|
65
|
+
}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
print "Switch to load/require#{unless use_loader; ' non';end} trace mode.\n" if verbose?
|
69
|
+
opt
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
#
|
3
|
+
# push-ws.rb -
|
4
|
+
# $Release Version: 0.9.6$
|
5
|
+
# $Revision$
|
6
|
+
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
7
|
+
#
|
8
|
+
# --
|
9
|
+
#
|
10
|
+
#
|
11
|
+
#
|
12
|
+
|
13
|
+
module IRB # :nodoc:
|
14
|
+
class Context
|
15
|
+
|
16
|
+
# Size of the current WorkSpace stack
|
17
|
+
def irb_level
|
18
|
+
workspace_stack.size
|
19
|
+
end
|
20
|
+
|
21
|
+
# WorkSpaces in the current stack
|
22
|
+
def workspaces
|
23
|
+
if defined? @workspaces
|
24
|
+
@workspaces
|
25
|
+
else
|
26
|
+
@workspaces = []
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Creates a new workspace with the given object or binding, and appends it
|
31
|
+
# onto the current #workspaces stack.
|
32
|
+
#
|
33
|
+
# See IRB::Context#change_workspace and IRB::WorkSpace.new for more
|
34
|
+
# information.
|
35
|
+
def push_workspace(*_main)
|
36
|
+
if _main.empty?
|
37
|
+
if workspaces.empty?
|
38
|
+
print "No other workspace\n"
|
39
|
+
return nil
|
40
|
+
end
|
41
|
+
ws = workspaces.pop
|
42
|
+
workspaces.push @workspace
|
43
|
+
@workspace = ws
|
44
|
+
return workspaces
|
45
|
+
end
|
46
|
+
|
47
|
+
workspaces.push @workspace
|
48
|
+
@workspace = WorkSpace.new(@workspace.binding, _main[0])
|
49
|
+
if !(class<<main;ancestors;end).include?(ExtendCommandBundle)
|
50
|
+
main.extend ExtendCommandBundle
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Removes the last element from the current #workspaces stack and returns
|
55
|
+
# it, or +nil+ if the current workspace stack is empty.
|
56
|
+
#
|
57
|
+
# Also, see #push_workspace.
|
58
|
+
def pop_workspace
|
59
|
+
if workspaces.empty?
|
60
|
+
print "workspace stack empty\n"
|
61
|
+
return
|
62
|
+
end
|
63
|
+
@workspace = workspaces.pop
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
@@ -0,0 +1,306 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
#
|
3
|
+
# irb/extend-command.rb - irb extend command
|
4
|
+
# $Release Version: 0.9.6$
|
5
|
+
# $Revision$
|
6
|
+
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
7
|
+
#
|
8
|
+
# --
|
9
|
+
#
|
10
|
+
#
|
11
|
+
#
|
12
|
+
module IRB # :nodoc:
|
13
|
+
# Installs the default irb extensions command bundle.
|
14
|
+
module ExtendCommandBundle
|
15
|
+
EXCB = ExtendCommandBundle # :nodoc:
|
16
|
+
|
17
|
+
# See #install_alias_method.
|
18
|
+
NO_OVERRIDE = 0
|
19
|
+
# See #install_alias_method.
|
20
|
+
OVERRIDE_PRIVATE_ONLY = 0x01
|
21
|
+
# See #install_alias_method.
|
22
|
+
OVERRIDE_ALL = 0x02
|
23
|
+
|
24
|
+
# Quits the current irb context
|
25
|
+
#
|
26
|
+
# +ret+ is the optional signal or message to send to Context#exit
|
27
|
+
#
|
28
|
+
# Same as <code>IRB.CurrentContext.exit</code>.
|
29
|
+
def irb_exit(ret = 0)
|
30
|
+
irb_context.exit(ret)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Displays current configuration.
|
34
|
+
#
|
35
|
+
# Modifing the configuration is achieved by sending a message to IRB.conf.
|
36
|
+
def irb_context
|
37
|
+
IRB.CurrentContext
|
38
|
+
end
|
39
|
+
|
40
|
+
@ALIASES = [
|
41
|
+
[:context, :irb_context, NO_OVERRIDE],
|
42
|
+
[:conf, :irb_context, NO_OVERRIDE],
|
43
|
+
[:irb_quit, :irb_exit, OVERRIDE_PRIVATE_ONLY],
|
44
|
+
[:exit, :irb_exit, OVERRIDE_PRIVATE_ONLY],
|
45
|
+
[:quit, :irb_exit, OVERRIDE_PRIVATE_ONLY],
|
46
|
+
]
|
47
|
+
|
48
|
+
@EXTEND_COMMANDS = [
|
49
|
+
[:irb_current_working_workspace, :CurrentWorkingWorkspace, "irb/cmd/chws",
|
50
|
+
[:irb_print_working_workspace, OVERRIDE_ALL],
|
51
|
+
[:irb_cwws, OVERRIDE_ALL],
|
52
|
+
[:irb_pwws, OVERRIDE_ALL],
|
53
|
+
[:cwws, NO_OVERRIDE],
|
54
|
+
[:pwws, NO_OVERRIDE],
|
55
|
+
[:irb_current_working_binding, OVERRIDE_ALL],
|
56
|
+
[:irb_print_working_binding, OVERRIDE_ALL],
|
57
|
+
[:irb_cwb, OVERRIDE_ALL],
|
58
|
+
[:irb_pwb, OVERRIDE_ALL],
|
59
|
+
],
|
60
|
+
[:irb_change_workspace, :ChangeWorkspace, "irb/cmd/chws",
|
61
|
+
[:irb_chws, OVERRIDE_ALL],
|
62
|
+
[:irb_cws, OVERRIDE_ALL],
|
63
|
+
[:chws, NO_OVERRIDE],
|
64
|
+
[:cws, NO_OVERRIDE],
|
65
|
+
[:irb_change_binding, OVERRIDE_ALL],
|
66
|
+
[:irb_cb, OVERRIDE_ALL],
|
67
|
+
[:cb, NO_OVERRIDE]],
|
68
|
+
|
69
|
+
[:irb_workspaces, :Workspaces, "irb/cmd/pushws",
|
70
|
+
[:workspaces, NO_OVERRIDE],
|
71
|
+
[:irb_bindings, OVERRIDE_ALL],
|
72
|
+
[:bindings, NO_OVERRIDE]],
|
73
|
+
[:irb_push_workspace, :PushWorkspace, "irb/cmd/pushws",
|
74
|
+
[:irb_pushws, OVERRIDE_ALL],
|
75
|
+
[:pushws, NO_OVERRIDE],
|
76
|
+
[:irb_push_binding, OVERRIDE_ALL],
|
77
|
+
[:irb_pushb, OVERRIDE_ALL],
|
78
|
+
[:pushb, NO_OVERRIDE]],
|
79
|
+
[:irb_pop_workspace, :PopWorkspace, "irb/cmd/pushws",
|
80
|
+
[:irb_popws, OVERRIDE_ALL],
|
81
|
+
[:popws, NO_OVERRIDE],
|
82
|
+
[:irb_pop_binding, OVERRIDE_ALL],
|
83
|
+
[:irb_popb, OVERRIDE_ALL],
|
84
|
+
[:popb, NO_OVERRIDE]],
|
85
|
+
|
86
|
+
[:irb_load, :Load, "irb/cmd/load"],
|
87
|
+
[:irb_require, :Require, "irb/cmd/load"],
|
88
|
+
[:irb_source, :Source, "irb/cmd/load",
|
89
|
+
[:source, NO_OVERRIDE]],
|
90
|
+
|
91
|
+
[:irb, :IrbCommand, "irb/cmd/subirb"],
|
92
|
+
[:irb_jobs, :Jobs, "irb/cmd/subirb",
|
93
|
+
[:jobs, NO_OVERRIDE]],
|
94
|
+
[:irb_fg, :Foreground, "irb/cmd/subirb",
|
95
|
+
[:fg, NO_OVERRIDE]],
|
96
|
+
[:irb_kill, :Kill, "irb/cmd/subirb",
|
97
|
+
[:kill, OVERRIDE_PRIVATE_ONLY]],
|
98
|
+
|
99
|
+
[:irb_help, :Help, "irb/cmd/help",
|
100
|
+
[:help, NO_OVERRIDE]],
|
101
|
+
|
102
|
+
]
|
103
|
+
|
104
|
+
# Installs the default irb commands:
|
105
|
+
#
|
106
|
+
# +irb_current_working_workspace+:: Context#main
|
107
|
+
# +irb_change_workspace+:: Context#change_workspace
|
108
|
+
# +irb_workspaces+:: Context#workspaces
|
109
|
+
# +irb_push_workspace+:: Context#push_workspace
|
110
|
+
# +irb_pop_workspace+:: Context#pop_workspace
|
111
|
+
# +irb_load+:: #irb_load
|
112
|
+
# +irb_require+:: #irb_require
|
113
|
+
# +irb_source+:: IrbLoader#source_file
|
114
|
+
# +irb+:: IRB.irb
|
115
|
+
# +irb_jobs+:: JobManager
|
116
|
+
# +irb_fg+:: JobManager#switch
|
117
|
+
# +irb_kill+:: JobManager#kill
|
118
|
+
# +irb_help+:: IRB@Command+line+options
|
119
|
+
def self.install_extend_commands
|
120
|
+
for args in @EXTEND_COMMANDS
|
121
|
+
def_extend_command(*args)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# Evaluate the given +cmd_name+ on the given +cmd_class+ Class.
|
126
|
+
#
|
127
|
+
# Will also define any given +aliases+ for the method.
|
128
|
+
#
|
129
|
+
# The optional +load_file+ parameter will be required within the method
|
130
|
+
# definition.
|
131
|
+
def self.def_extend_command(cmd_name, cmd_class, load_file = nil, *aliases)
|
132
|
+
case cmd_class
|
133
|
+
when Symbol
|
134
|
+
cmd_class = cmd_class.id2name
|
135
|
+
when String
|
136
|
+
when Class
|
137
|
+
cmd_class = cmd_class.name
|
138
|
+
end
|
139
|
+
|
140
|
+
if load_file
|
141
|
+
line = __LINE__; eval %[
|
142
|
+
def #{cmd_name}(*opts, &b)
|
143
|
+
require "#{load_file}"
|
144
|
+
arity = ExtendCommand::#{cmd_class}.instance_method(:execute).arity
|
145
|
+
args = (1..(arity < 0 ? ~arity : arity)).map {|i| "arg" + i.to_s }
|
146
|
+
args << "*opts" if arity < 0
|
147
|
+
args << "&block"
|
148
|
+
args = args.join(", ")
|
149
|
+
line = __LINE__; eval %[
|
150
|
+
def #{cmd_name}(\#{args})
|
151
|
+
ExtendCommand::#{cmd_class}.execute(irb_context, \#{args})
|
152
|
+
end
|
153
|
+
], nil, __FILE__, line
|
154
|
+
send :#{cmd_name}, *opts, &b
|
155
|
+
end
|
156
|
+
], nil, __FILE__, line
|
157
|
+
else
|
158
|
+
line = __LINE__; eval %[
|
159
|
+
def #{cmd_name}(*opts, &b)
|
160
|
+
ExtendCommand::#{cmd_class}.execute(irb_context, *opts, &b)
|
161
|
+
end
|
162
|
+
], nil, __FILE__, line
|
163
|
+
end
|
164
|
+
|
165
|
+
for ali, flag in aliases
|
166
|
+
@ALIASES.push [ali, cmd_name, flag]
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
# Installs alias methods for the default irb commands, see
|
171
|
+
# ::install_extend_commands.
|
172
|
+
def install_alias_method(to, from, override = NO_OVERRIDE)
|
173
|
+
to = to.id2name unless to.kind_of?(String)
|
174
|
+
from = from.id2name unless from.kind_of?(String)
|
175
|
+
|
176
|
+
if override == OVERRIDE_ALL or
|
177
|
+
(override == OVERRIDE_PRIVATE_ONLY) && !respond_to?(to) or
|
178
|
+
(override == NO_OVERRIDE) && !respond_to?(to, true)
|
179
|
+
target = self
|
180
|
+
(class << self; self; end).instance_eval{
|
181
|
+
if target.respond_to?(to, true) &&
|
182
|
+
!target.respond_to?(EXCB.irb_original_method_name(to), true)
|
183
|
+
alias_method(EXCB.irb_original_method_name(to), to)
|
184
|
+
end
|
185
|
+
alias_method to, from
|
186
|
+
}
|
187
|
+
else
|
188
|
+
print "irb: warn: can't alias #{to} from #{from}.\n"
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def self.irb_original_method_name(method_name) # :nodoc:
|
193
|
+
"irb_" + method_name + "_org"
|
194
|
+
end
|
195
|
+
|
196
|
+
# Installs alias methods for the default irb commands on the given object
|
197
|
+
# using #install_alias_method.
|
198
|
+
def self.extend_object(obj)
|
199
|
+
unless (class << obj; ancestors; end).include?(EXCB)
|
200
|
+
super
|
201
|
+
for ali, com, flg in @ALIASES
|
202
|
+
obj.install_alias_method(ali, com, flg)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
install_extend_commands
|
208
|
+
end
|
209
|
+
|
210
|
+
# Extends methods for the Context module
|
211
|
+
module ContextExtender
|
212
|
+
CE = ContextExtender # :nodoc:
|
213
|
+
|
214
|
+
@EXTEND_COMMANDS = [
|
215
|
+
[:eval_history=, "irb/ext/history.rb"],
|
216
|
+
[:use_tracer=, "irb/ext/tracer.rb"],
|
217
|
+
[:use_loader=, "irb/ext/use-loader.rb"],
|
218
|
+
[:save_history=, "irb/ext/save-history.rb"],
|
219
|
+
]
|
220
|
+
|
221
|
+
# Installs the default context extensions as irb commands:
|
222
|
+
#
|
223
|
+
# Context#eval_history=:: +irb/ext/history.rb+
|
224
|
+
# Context#use_tracer=:: +irb/ext/tracer.rb+
|
225
|
+
# Context#use_loader=:: +irb/ext/use-loader.rb+
|
226
|
+
# Context#save_history=:: +irb/ext/save-history.rb+
|
227
|
+
def self.install_extend_commands
|
228
|
+
for args in @EXTEND_COMMANDS
|
229
|
+
def_extend_command(*args)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
# Evaluate the given +command+ from the given +load_file+ on the Context
|
234
|
+
# module.
|
235
|
+
#
|
236
|
+
# Will also define any given +aliases+ for the method.
|
237
|
+
def self.def_extend_command(cmd_name, load_file, *aliases)
|
238
|
+
line = __LINE__; Context.module_eval %[
|
239
|
+
def #{cmd_name}(*opts, &b)
|
240
|
+
Context.module_eval {remove_method(:#{cmd_name})}
|
241
|
+
require "#{load_file}"
|
242
|
+
send :#{cmd_name}, *opts, &b
|
243
|
+
end
|
244
|
+
for ali in aliases
|
245
|
+
alias_method ali, cmd_name
|
246
|
+
end
|
247
|
+
], __FILE__, line
|
248
|
+
end
|
249
|
+
|
250
|
+
CE.install_extend_commands
|
251
|
+
end
|
252
|
+
|
253
|
+
# A convenience module for extending Ruby methods.
|
254
|
+
module MethodExtender
|
255
|
+
# Extends the given +base_method+ with a prefix call to the given
|
256
|
+
# +extend_method+.
|
257
|
+
def def_pre_proc(base_method, extend_method)
|
258
|
+
base_method = base_method.to_s
|
259
|
+
extend_method = extend_method.to_s
|
260
|
+
|
261
|
+
alias_name = new_alias_name(base_method)
|
262
|
+
module_eval %[
|
263
|
+
alias_method alias_name, base_method
|
264
|
+
def #{base_method}(*opts)
|
265
|
+
send :#{extend_method}, *opts
|
266
|
+
send :#{alias_name}, *opts
|
267
|
+
end
|
268
|
+
]
|
269
|
+
end
|
270
|
+
|
271
|
+
# Extends the given +base_method+ with a postfix call to the given
|
272
|
+
# +extend_method+.
|
273
|
+
def def_post_proc(base_method, extend_method)
|
274
|
+
base_method = base_method.to_s
|
275
|
+
extend_method = extend_method.to_s
|
276
|
+
|
277
|
+
alias_name = new_alias_name(base_method)
|
278
|
+
module_eval %[
|
279
|
+
alias_method alias_name, base_method
|
280
|
+
def #{base_method}(*opts)
|
281
|
+
send :#{alias_name}, *opts
|
282
|
+
send :#{extend_method}, *opts
|
283
|
+
end
|
284
|
+
]
|
285
|
+
end
|
286
|
+
|
287
|
+
# Returns a unique method name to use as an alias for the given +name+.
|
288
|
+
#
|
289
|
+
# Usually returns <code>#{prefix}#{name}#{postfix}<num></code>, example:
|
290
|
+
#
|
291
|
+
# new_alias_name('foo') #=> __alias_of__foo__
|
292
|
+
# def bar; end
|
293
|
+
# new_alias_name('bar') #=> __alias_of__bar__2
|
294
|
+
def new_alias_name(name, prefix = "__alias_of__", postfix = "__")
|
295
|
+
base_name = "#{prefix}#{name}#{postfix}"
|
296
|
+
all_methods = instance_methods(true) + private_instance_methods(true)
|
297
|
+
same_methods = all_methods.grep(/^#{Regexp.quote(base_name)}[0-9]*$/)
|
298
|
+
return base_name if same_methods.empty?
|
299
|
+
no = same_methods.size
|
300
|
+
while !same_methods.include?(alias_name = base_name + no)
|
301
|
+
no += 1
|
302
|
+
end
|
303
|
+
alias_name
|
304
|
+
end
|
305
|
+
end
|
306
|
+
end
|