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