irb 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|