PageRenderTime 151ms CodeModel.GetById 102ms app.highlight 44ms RepoModel.GetById 1ms app.codeStats 0ms

/tools/Ruby/lib/ruby/1.8/irb/extend-command.rb

http://github.com/agross/netopenspace
Ruby | 269 lines | 223 code | 16 blank | 30 comment | 12 complexity | a8646ef4de5da8da01dc68869f46358d MD5 | raw file
  1#
  2#   irb/extend-command.rb - irb extend command 
  3#   	$Release Version: 0.9.5$
  4#   	$Revision: 25814 $
  5#   	$Date: 2009-11-17 15:51:29 +0900 (Tue, 17 Nov 2009) $
  6#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
  7#
  8# --
  9#
 10#   
 11#
 12module IRB
 13  #
 14  # IRB extended command
 15  #
 16  module ExtendCommandBundle
 17    EXCB = ExtendCommandBundle
 18
 19    NO_OVERRIDE = 0
 20    OVERRIDE_PRIVATE_ONLY = 0x01
 21    OVERRIDE_ALL = 0x02
 22
 23    def irb_exit(ret = 0)
 24      irb_context.exit(ret)
 25    end
 26
 27    def irb_context
 28      IRB.CurrentContext
 29    end
 30
 31    @ALIASES = [
 32      [:context, :irb_context, NO_OVERRIDE],
 33      [:conf, :irb_context, NO_OVERRIDE],
 34      [:irb_quit, :irb_exit, OVERRIDE_PRIVATE_ONLY],
 35      [:exit, :irb_exit, OVERRIDE_PRIVATE_ONLY],
 36      [:quit, :irb_exit, OVERRIDE_PRIVATE_ONLY],
 37    ]
 38
 39    @EXTEND_COMMANDS = [
 40      [:irb_current_working_workspace, :CurrentWorkingWorkspace, "irb/cmd/chws",
 41	[:irb_print_working_workspace, OVERRIDE_ALL],
 42	[:irb_cwws, OVERRIDE_ALL],
 43	[:irb_pwws, OVERRIDE_ALL],
 44#	[:irb_cww, OVERRIDE_ALL],
 45#	[:irb_pww, OVERRIDE_ALL],
 46	[:cwws, NO_OVERRIDE],
 47	[:pwws, NO_OVERRIDE],
 48#	[:cww, NO_OVERRIDE],
 49#	[:pww, NO_OVERRIDE],
 50	[:irb_current_working_binding, OVERRIDE_ALL],
 51	[:irb_print_working_binding, OVERRIDE_ALL],
 52	[:irb_cwb, OVERRIDE_ALL],
 53	[:irb_pwb, OVERRIDE_ALL],
 54#	[:cwb, NO_OVERRIDE],
 55#	[:pwb, NO_OVERRIDE]
 56      ],
 57      [:irb_change_workspace, :ChangeWorkspace, "irb/cmd/chws",
 58	[:irb_chws, OVERRIDE_ALL],
 59#	[:irb_chw, OVERRIDE_ALL],
 60	[:irb_cws, OVERRIDE_ALL],
 61#	[:irb_cw, OVERRIDE_ALL],
 62	[:chws, NO_OVERRIDE],
 63#	[:chw, NO_OVERRIDE],
 64	[:cws, NO_OVERRIDE],
 65#	[:cw, NO_OVERRIDE],
 66	[:irb_change_binding, OVERRIDE_ALL],
 67	[:irb_cb, OVERRIDE_ALL],
 68	[:cb, NO_OVERRIDE]],
 69
 70      [:irb_workspaces, :Workspaces, "irb/cmd/pushws",
 71	[:workspaces, NO_OVERRIDE],
 72	[:irb_bindings, OVERRIDE_ALL],
 73	[:bindings, NO_OVERRIDE]],
 74      [:irb_push_workspace, :PushWorkspace, "irb/cmd/pushws",
 75	[:irb_pushws, OVERRIDE_ALL],
 76#	[:irb_pushw, OVERRIDE_ALL],
 77	[:pushws, NO_OVERRIDE],
 78#	[:pushw, NO_OVERRIDE],
 79	[:irb_push_binding, OVERRIDE_ALL],
 80	[:irb_pushb, OVERRIDE_ALL],
 81	[:pushb, NO_OVERRIDE]],
 82      [:irb_pop_workspace, :PopWorkspace, "irb/cmd/pushws",
 83	[:irb_popws, OVERRIDE_ALL],
 84#	[:irb_popw, OVERRIDE_ALL],
 85	[:popws, NO_OVERRIDE],
 86#	[:popw, NO_OVERRIDE],
 87	[:irb_pop_binding, OVERRIDE_ALL],
 88	[:irb_popb, OVERRIDE_ALL],
 89	[:popb, NO_OVERRIDE]],
 90
 91      [:irb_load, :Load, "irb/cmd/load"],
 92      [:irb_require, :Require, "irb/cmd/load"],
 93      [:irb_source, :Source, "irb/cmd/load", 
 94	[:source, NO_OVERRIDE]],
 95
 96      [:irb, :IrbCommand, "irb/cmd/subirb"],
 97      [:irb_jobs, :Jobs, "irb/cmd/subirb", 
 98	[:jobs, NO_OVERRIDE]],
 99      [:irb_fg, :Foreground, "irb/cmd/subirb", 
100	[:fg, NO_OVERRIDE]],
101      [:irb_kill, :Kill, "irb/cmd/subirb", 
102	[:kill, OVERRIDE_PRIVATE_ONLY]],
103
104      [:irb_help, :Help, "irb/cmd/help",
105        [:help, NO_OVERRIDE]],
106
107    ]
108
109    def self.install_extend_commands
110      for args in @EXTEND_COMMANDS
111	def_extend_command(*args)
112      end
113    end
114
115    # aliases = [commands_alias, flag], ...
116    def self.def_extend_command(cmd_name, cmd_class, load_file = nil, *aliases)
117      case cmd_class
118      when Symbol
119	cmd_class = cmd_class.id2name
120      when String
121      when Class
122	cmd_class = cmd_class.name
123      end
124
125      if load_file
126	eval %[
127	  def #{cmd_name}(*opts, &b)
128	    require "#{load_file}"
129	    arity = ExtendCommand::#{cmd_class}.instance_method(:execute).arity
130	    args = (1..arity.abs).map {|i| "arg" + i.to_s }
131	    args << "*opts" if arity < 0
132	    args << "&block"
133	    args = args.join(", ")
134	    eval %[
135	      def #{cmd_name}(\#{args})
136		ExtendCommand::#{cmd_class}.execute(irb_context, \#{args})
137	      end
138	    ]
139	    send :#{cmd_name}, *opts, &b
140	  end
141	]
142      else
143	eval %[
144	  def #{cmd_name}(*opts, &b)
145	    ExtendCommand::#{cmd_class}.execute(irb_context, *opts, &b)
146	  end
147	]
148      end
149
150      for ali, flag in aliases
151	@ALIASES.push [ali, cmd_name, flag]
152      end
153    end
154
155    # override = {NO_OVERRIDE, OVERRIDE_PRIVATE_ONLY, OVERRIDE_ALL}
156    def install_alias_method(to, from, override = NO_OVERRIDE)
157      to = to.id2name unless to.kind_of?(String)
158      from = from.id2name unless from.kind_of?(String)
159
160      if override == OVERRIDE_ALL or
161	  (override == OVERRIDE_PRIVATE_ONLY) && !respond_to?(to) or
162	  (override == NO_OVERRIDE) &&  !respond_to?(to, true)
163	target = self
164	(class<<self;self;end).instance_eval{
165	  if target.respond_to?(to, true) && 
166	      !target.respond_to?(EXCB.irb_original_method_name(to), true)
167	    alias_method(EXCB.irb_original_method_name(to), to) 
168	  end
169	  alias_method to, from
170	}
171      else
172	print "irb: warn: can't alias #{to} from #{from}.\n"
173      end
174    end
175
176    def self.irb_original_method_name(method_name)
177      "irb_" + method_name + "_org"
178    end
179
180    def self.extend_object(obj)
181      unless (class<<obj;ancestors;end).include?(EXCB)
182	super
183	for ali, com, flg in @ALIASES
184	  obj.install_alias_method(ali, com, flg)
185	end
186      end
187    end
188
189    install_extend_commands
190  end
191
192  # extension support for Context
193  module ContextExtender
194    CE = ContextExtender
195
196    @EXTEND_COMMANDS = [
197      [:eval_history=, "irb/ext/history.rb"],
198      [:use_tracer=, "irb/ext/tracer.rb"],
199      [:math_mode=, "irb/ext/math-mode.rb"],
200      [:use_loader=, "irb/ext/use-loader.rb"],
201      [:save_history=, "irb/ext/save-history.rb"],
202    ]
203
204    def self.install_extend_commands
205      for args in @EXTEND_COMMANDS
206	def_extend_command(*args)
207      end
208    end
209
210    def self.def_extend_command(cmd_name, load_file, *aliases)
211      Context.module_eval %[
212        def #{cmd_name}(*opts, &b)
213	  Context.module_eval {remove_method(:#{cmd_name})}
214	  require "#{load_file}"
215	  send :#{cmd_name}, *opts, &b
216	end
217	for ali in aliases
218	  alias_method ali, cmd_name
219	end
220      ]
221    end
222
223    CE.install_extend_commands
224  end
225
226  module MethodExtender
227    def def_pre_proc(base_method, extend_method)
228      base_method = base_method.to_s
229      extend_method = extend_method.to_s
230
231      alias_name = new_alias_name(base_method)
232      module_eval %[
233        alias_method alias_name, base_method
234        def #{base_method}(*opts)
235	  send :#{extend_method}, *opts
236	  send :#{alias_name}, *opts
237	end
238      ]
239    end
240
241    def def_post_proc(base_method, extend_method)
242      base_method = base_method.to_s
243      extend_method = extend_method.to_s
244
245      alias_name = new_alias_name(base_method)
246      module_eval %[
247        alias_method alias_name, base_method
248        def #{base_method}(*opts)
249	  send :#{alias_name}, *opts
250	  send :#{extend_method}, *opts
251	end
252      ]
253    end
254
255    # return #{prefix}#{name}#{postfix}<num>
256    def new_alias_name(name, prefix = "__alias_of__", postfix = "__")
257      base_name = "#{prefix}#{name}#{postfix}"
258      all_methods = instance_methods(true) + private_instance_methods(true)
259      same_methods = all_methods.grep(/^#{Regexp.quote(base_name)}[0-9]*$/)
260      return base_name if same_methods.empty?
261      no = same_methods.size
262      while !same_methods.include?(alias_name = base_name + no)
263	no += 1
264      end
265      alias_name
266    end
267  end
268end
269