diff options
author | knu <knu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-04-30 17:38:21 +0000 |
---|---|---|
committer | knu <knu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-04-30 17:38:21 +0000 |
commit | 0b36b7976239b6e03fb47def9e41d1c17e7b38ec (patch) | |
tree | f5b4f478538ea7c4cc541fda4fe5a30274e472ed | |
parent | fd31cfaaea0825cc0634c0d2294499420302ca7e (diff) | |
download | ruby-0b36b7976239b6e03fb47def9e41d1c17e7b38ec.tar.gz ruby-0b36b7976239b6e03fb47def9e41d1c17e7b38ec.tar.xz ruby-0b36b7976239b6e03fb47def9e41d1c17e7b38ec.zip |
Initial revision
git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@1337 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | doc/irb/irb.rd | 377 | ||||
-rw-r--r-- | doc/irb/irb.rd.jp | 391 | ||||
-rw-r--r-- | lib/irb.rb | 317 | ||||
-rw-r--r-- | lib/irb/context.rb | 290 | ||||
-rw-r--r-- | lib/irb/extend-command.rb | 127 | ||||
-rw-r--r-- | lib/irb/help.rb | 33 | ||||
-rw-r--r-- | lib/irb/init.rb | 238 | ||||
-rw-r--r-- | lib/irb/lc/error.rb | 30 | ||||
-rw-r--r-- | lib/irb/lc/help-message | 34 | ||||
-rw-r--r-- | lib/irb/lc/ja/error.rb | 29 | ||||
-rw-r--r-- | lib/irb/lc/ja/help-message | 35 | ||||
-rw-r--r-- | lib/irb/locale.rb | 187 | ||||
-rw-r--r-- | lib/irb/workspace.rb | 106 | ||||
-rw-r--r-- | lib/irb/ws-for-case-2.rb | 15 |
14 files changed, 2209 insertions, 0 deletions
diff --git a/doc/irb/irb.rd b/doc/irb/irb.rd new file mode 100644 index 000000000..77b59639d --- /dev/null +++ b/doc/irb/irb.rd @@ -0,0 +1,377 @@ +irb -- interactive ruby + $Release Version: 0.5 $ + $Revision$ + $Date$ + by Keiju ISHITSUKA(keiju@ishitsuka.com) + translate from japanese by gotoken-san + +==begin += What is irb? + +irb stands for `interactive ruby'. irb is a tool to execute interactively +ruby expressions read from stdin. + += Invoking + + % ruby -r irb -e0 + % irb + +Either of the aboves. In the former style, options can be specified +as follows: + + % ruby -r irb -e0 -- -v + += Usage + +Use of irb is easy if you know ruby. Executing irb, prompts are +displayed as follows. Then, enter expression of ruby. A input is +executed when it is syntacticaly completed. + + dim% irb + irb(main):001:0> 1+2 + 3 + irb(main):002:0> class Foo + irb(main):003:1> def foo + irb(main):004:2> print 1 + irb(main):005:2> end + irb(main):006:1> end + nil + irb(main):007:0> + +And, Readline extesion module can be used with irb. Using Readline +is the standard default action if Readline is installed. + += Command line option + + irb.rb [options] file_name opts + options: + -f suppress read ~/.irbrc + -m bc mode (fraction or matrix are available) + -d set $DEBUG to true (same as `ruby -d') + -r load-module same as `ruby -r' + --inspect uses `inspect' for output (the default except bc mode) + --noinspect doesn't uses inspect for output + --readline uses Readline extension module + --noreadline doesn't use Readline extension module + --prompt prompt-mode + --prompt-mode prompt-mode + switches prompt mode. Pre-defined prompt modes are + `defalut', `simple', `xmp' and `inf-ruby' + + --inf-ruby-mode uses prompt appreciate for inf-ruby-mode on emacs. + Suppresses --readline. + --simple-prompt simple prompt mode + --noprompt no prompt + --tracer display trace for each execution of commands. + --back-trace-limit n + displayes backtrace top n and tail n. The default + value is 16. + --irb_debug n sets internal debug level to n (It shouldn't be used) + -v, --version prints the version of irb + + + += Configurations + +irb reads `~/.irbrc' when it is invoked. If `~/.irbrb' doesn't exist +irb try to read in the order `.irbrc', `irb.rc', `_irbrc' then `$irbrc'. + +The following is altanative to the command line option. To use them +type as follows in an irb session. + + IRB.conf[:IRB_NAME]="irb" + IRB.conf[:MATH_MODE]=false + IRB.conf[:USE_TRACER]=false + IRB.conf[:USE_LOADER]=false + IRB.conf[:IGNORE_SIGINT]=true + IRB.conf[:IGNORE_EOF]=false + IRB.conf[:INSPECT_MODE]=nil + IRB.conf[:IRB_RC] = nil + IRB.conf[:BACK_TRACE_LIMIT]=16 + IRB.conf[:USE_LOADER] = false + IRB.conf[:USE_READLINE] = nil + IRB.conf[:USE_TRACER] = false + IRB.conf[:IGNORE_SIGINT] = true + IRB.conf[:IGNORE_EOF] = false + IRB.conf[:PROMPT_MODE] = :DEFALUT + IRB.conf[:PROMPT] = {...} + IRB.conf[:DEBUG_LEVEL]=0 + IRB.conf[:VERBOSE]=true + +== Customizing prompt + +To costomize the prompt you set a variable + + IRB.conf[:PROMPT] + +For example, describe as follows in `.irbrc'. + + IRB.conf[:PROMPT][:MY_PROMPT] = { # name of prompt mode + :PROMPT_I => nil, # normal prompt + :PROMPT_S => nil, # prompt for continuated strings + :PROMPT_C => nil, # prompt for continuated statement + :RETURN => " ==>%s\n" # format to return value + } + +Then, invoke irb with the above prompt mode by + + % irb --prompt my-prompt + +Or add the following in `.irbrc'. + + IRB.conf[:PROMPT_MODE] = :MY_PROMPT + +Constants PROMPT_I, PROMPT_S and PROMPT_C specifies the format. +In the prompt specification, some special strings are available. + + %N command name which is running + %m to_s of main object (self) + %M inspect of main object (self) + %l type of string(", ', /, ]), `]' is inner %w[...] + %NNi indent level. NN is degits and means as same as printf("%NNd"). + It can be ommited + %NNn line number. + %% % + +For instance, the default prompt mode is defined as follows: + +IRB.conf[:PROMPT_MODE][:DEFAULT] = { + :PROMPT_I => "%N(%m):%03n:%i> ", + :PROMPT_S => "%N(%m):%03n:%i%l ", + :PROMPT_C => "%N(%m):%03n:%i* ", + :RETURN => "%s\n" +} + +RETURN is used to printf. + +== Configurating subirb + +The command line option or IRB.conf specify the default behavior of +(sub)irb. On the other hand, each conf of in the next sction `6. Command' +is used to individually configurate (sub)irb. + +If proc is set to IRB.conf[:IRB_RC], its subirb will be invoked after +execution of that proc under giving the context of irb as its +aregument. By this mechanism each subirb can be configurated. + += Command + +For irb commands, both simple name and `irb_'-prefixed name are prepared. + +--- exit, quit, irb_exit + Quits (sub)irb. + if you've done cb (see below), exit from the binding mode. + +--- conf, irb_context + Displays current configuration. Modifing the configuration is + achieved by sending message to `conf'. + +--- conf.back_trace_limit + Sets display lines of backtrace as top n and tail n. + The default value is 16. + +--- conf.debug_level = N + Sets debug level of irb. + +--- conf.ignore_eof = true/false + Whether ^D (control-d) will be ignored or not. + If false is set, ^D means quit. + +--- conf.ignore_sigint= true/false + Whether ^C (control-c) will be ignored or not. + If false is set, ^D means quit. If true, + during input: cancel inputing then return to top level. + during execute: abondon current execution. + +--- conf.inf_ruby_mode = true/false + Whether inf-ruby-mode or not. The default value is false. + +--- conf.inspect_mode = true/false/nil + Specifies inspect mode. + true: display inspect + false: display to_s + nil: inspect mode in non math mode, + non inspect mode in math mode. + +--- conf.irb_level + The level of cb. + +--- conf.math_mode + Whether bc mode or not. + +--- conf.use_loader = true/false + Whether irb's own file reader method is used when load/require or not. + This mode is globaly affected (irb wide). + +--- conf.prompt_c + prompt for a continuating statement (e.g, immediately after of `if') + +--- conf.prompt_i + standard prompt + +--- conf.prompt_s + prompt for a continuating string + +--- conf.rc + Whether ~/.irbrc is read or not. + +--- conf.use_prompt = true/false + Prompting or not. + +--- conf.use_readline = true/false/nil + Whether readline is used or not. + true: uses + false: doen't use + nil: intends to use readline except for inf-reuby-mode (default) + +--- conf.verbose=T/F + Whether verbose messages are display or not. + +--- cb, irb_change_binding [obj] + Enter new binding which has a distinct scope of local variables. + If obj is given, obj will be self. + +--- irb [obj] + Invoke subirb. If obj is given, obj will be self. + +--- jobs, irb_jobs + List of subirb + +--- fg n, irb_fg n + Switch into specified subirb. The following is candidates of n: + + irb number + thhread + irb object + self(obj which is specified of irb obj) + +--- kill n, irb_kill n + Kill subirb. The means of n is as same as the case of irb_fg. + += System variable + + _ The latest value of evaluation (it is local) + + += Session Example + + dim% ruby irb.rb + irb(main):001:0> irb # invoke subirb + irb#1(main):001:0> jobs # list of subirbs + #0->irb on main (#<Thread:0x400fb7e4> : stop) + #1->irb#1 on main (#<Thread:0x40125d64> : running) + nil + irb#1(main):002:0> fg 0 # switch job + nil + irb(main):002:0> class Foo;end + nil + irb(main):003:0> irb Foo # invoke subirb which has the + # context of Foo + irb#2(Foo):001:0> def foo # define Foo#foo + irb#2(Foo):002:1> print 1 + irb#2(Foo):003:1> end + nil + irb#2(Foo):004:0> fg 0 # switch job + nil + irb(main):004:0> jobs # list of job + #0->irb on main (#<Thread:0x400fb7e4> : running) + #1->irb#1 on main (#<Thread:0x40125d64> : stop) + #2->irb#2 on Foo (#<Thread:0x4011d54c> : stop) + nil + irb(main):005:0> Foo.instance_methods # Foo#foo is defined asurely + ["foo"] + irb(main):006:0> fg 2 # switch job + nil + irb#2(Foo):005:0> def bar # define Foo#bar + irb#2(Foo):006:1> print "bar" + irb#2(Foo):007:1> end + nil + irb#2(Foo):010:0> Foo.instance_methods + ["bar", "foo"] + irb#2(Foo):011:0> fg 0 + nil + irb(main):007:0> f = Foo.new + #<Foo:0x4010af3c> + irb(main):008:0> irb f # invoke subirb which has the + # context of f (instance of Foo) + irb#3(#<Foo:0x4010af3c>):001:0> jobs + #0->irb on main (#<Thread:0x400fb7e4> : stop) + #1->irb#1 on main (#<Thread:0x40125d64> : stop) + #2->irb#2 on Foo (#<Thread:0x4011d54c> : stop) + #3->irb#3 on #<Foo:0x4010af3c> (#<Thread:0x4010a1e0> : running) + nil + irb#3(#<Foo:0x4010af3c>):002:0> foo # evaluate f.foo + 1nil + irb#3(#<Foo:0x4010af3c>):003:0> bar # evaluate f.bar + barnil + irb#3(#<Foo:0x4010af3c>):004:0> kill 1, 2, 3# kill job + nil + irb(main):009:0> jobs + #0->irb on main (#<Thread:0x400fb7e4> : running) + nil + irb(main):010:0> exit # exit + dim% + += Restrictions + +Because irb evaluates the inputs immediately after the imput is +syntactically completed, irb gives slight different result than +directly use ruby. Known difference is pointed out here. + + +== Declaration of the local variable + +The following causes an error in ruby: + + eval "foo = 0" + foo + -- + -:2: undefined local variable or method `foo' for #<Object:0x40283118> (NameError) + --- + NameError + +Though, the above will successfully done by irb. + + >> eval "foo = 0" + => 0 + >> foo + => 0 + +Ruby evaluates a code after reading entire of code and determination +of the scope of local variables. On the other hand, irb do +immediately. More precisely, irb evaluate at first + + evel "foo = 0" + +then foo is defined on this timing. It is because of this +incompatibility. + +If you'd like to detect those differences, begin...end can be used: + + >> begin + ?> eval "foo = 0" + >> foo + >> end + NameError: undefined local variable or method `foo' for #<Object:0x4013d0f0> + (irb):3 + (irb_local_binding):1:in `eval' + +== Here-document + +Implementation of Here-document is incomplete. + +== Symbol + +Irb can not always recognize a symbol as to be Symbol. Concretely, an +expression have completed, however Irb regard it as continuation line. + +==end + +% Begin Emacs Environment +% Local Variables: +% mode: text +% comment-column: 0 +% comment-start: "%" +% comment-end: "\n" +% End: +% diff --git a/doc/irb/irb.rd.jp b/doc/irb/irb.rd.jp new file mode 100644 index 000000000..cf65d3e3c --- /dev/null +++ b/doc/irb/irb.rd.jp @@ -0,0 +1,391 @@ +irb -- interactive ruby + $Release Version: 0.6 $ + $Revision$ + $Date$ + by Keiju ISHITSUKA(keiju@ishitsuka.com) +==begin += irb$B$H$O(B? + +irb$B$O(Binteractive ruby$B$NN,$G$9(B. ruby$B$N<0$rI8=`F~NO$+$i4JC1$KF~NO(B/$B<B9T$9(B +$B$k$?$a$N%D!<%k$G$9(B. + += $B5/F0(B + + % ruby -r irb -e0 + % irb + +$B$N$$$:$l$+$G9T$J$$$^$9(B. $BA0<T$N>l9g(Birb$B$X$N%*%W%7%g%s;XDj$O(B, $B0J2<$N$h$&$K(B +$B$J$j$^$9(B. + + % ruby -r irb -e0 -- -v + += $B;H$$J}(B + +irb$B$N;H$$J}$O(B, Ruby$B$5$(CN$C$F$$$l$P$$$?$C$F4JC1$G$9(B. $B4pK\E*$K$O(B irb $B$H(B +$B$$$&%3%^%s%I$r<B9T$9$k$@$1$G$9(B. irb$B$r<B9T$9$k$H(B, $B0J2<$N$h$&$J%W%m%s%W(B +$B%H$,I=$l$F$-$^$9(B. $B8e$O(B, ruby$B$N<0$rF~$l$F2<$5$$(B. $B<0$,407k$7$?;~E@$G<B9T(B +$B$5$l$^$9(B. + + dim% irb + irb(main):001:0> 1+2 + 3 + irb(main):002:0> class Foo + irb(main):003:1> def foo + irb(main):004:2> print 1 + irb(main):005:2> end + irb(main):006:1> end + nil + irb(main):007:0> + +$B$^$?(B, irb$B$O(BReadline$B%b%8%e!<%k$K$bBP1~$7$F$$$^$9(B. Readline$B%b%8%e!<%k$,(B +$B%$%s%9%H!<%k$5$l$F$$$k;~$K$O(B, $B$=$l$r;H$&$N$,I8=`$NF0:n$K$J$j$^$9(B. + += $B%3%^%s%I%*%W%7%g%s(B + + irb.rb [options] file_name opts + options: + -f ~/.irbrc $B$rFI$_9~$^$J$$(B. + -m bc$B%b!<%I(B($BJ,?t(B, $B9TNs$N7W;;$,$G$-$k(B) + -d $DEBUG $B$r(Btrue$B$K$9$k(B(ruby -d $B$HF1$8(B) + -r load-module ruby -r $B$HF1$8(B. + --inspect $B7k2L=PNO$K(Binspect$B$rMQ$$$k(B(bc$B%b!<%I0J30$O%G%U%)%k%H(B). + --noinspect $B7k2L=PNO$K(Binspect$B$rMQ$$$J$$(B. + --readline readline$B%i%$%V%i%j$rMxMQ$9$k(B. + --noreadline readline$B%i%$%V%i%j$rMxMQ$7$J$$(B. $B%G%U%)%k%H$NF0:n$O(B, + inf-reuby-mode$B0J30$G(Breadline$B%i%$%V%i%j$rMxMQ$7$h$&(B + $B$H$9$k(B. + --prompt prompt-mode + --prompt-mode prompt-mode + $B%W%m%s%W%H%b!<%I$r@ZBX$($^$9(B. $B8=:_Dj5A$5$l$F$$$k%W(B + $B%m%s%W%H%b!<%I$O(B, defalut, simple, xmp, inf-ruby$B$,(B + $BMQ0U$5$l$F$$$^$9(B. $B%G%U%)%k%H$O(Bdefault$B%W%m%s%W%H%b!<(B + $B%I$K$J$C$F$$$^$9(B. + + --inf-ruby-mode emacs$B$N(Binf-ruby-mode$BMQ$N%W%m%s%W%HI=<($r9T$J$&(B. $BFC(B + $B$K;XDj$,$J$$8B$j(B, readline$B%i%$%V%i%j$O;H$o$J$/$J$k(B. + --simple-prompt + $BHs>o$K%7%s%W%k$J%W%m%s%W%H$rMQ$$$k%b!<%I$G$9(B. + --noprompt $B%W%m%s%W%HI=<($r9T$J$o$J$$(B. + --tracer $B%3%^%s%I<B9T;~$K%H%l!<%9$r9T$J$&(B. + --back-trace-limit n + $B%P%C%/%H%l!<%9I=<($r%P%C%/%H%l!<%9$NF,$+$i(B n, $B8e$m(B + $B$+$i(Bn$B$@$19T$J$&(B. $B%G%U%)%k%H$O(B16 + --irb_debug n irb$B$N%G%P%C%0%G%P%C%0%l%Y%k$r(Bn$B$K@_Dj$9$k(B($BMxMQ$7$J(B + $B$$J}$,L5Fq$G$7$g$&(B). + -v, --version irb$B$N%P!<%8%g%s$rI=<($9$k(B + += $B%3%s%U%#%.%e%l!<%7%g%s(B + +irb$B5/F0;~$K(B``~/.irbrc''$B$rFI$_9~$_$^$9(B. $B$b$7B8:_$7$J$$>l9g$O(B, +``.irbrc'', ``irb.rc'', ``_irbrc'', ``$irbrc''$B$N=g$K(Bload$B$r;n$_$^$9(B. + +$B%*%W%7%g%s$r@_Dj$9$kBe$o$j$K(B, $B0J2<$N%3%^%s%I$G$b%G%U%)%k%H$NF0:n$r@_Dj(B +$B$G$-$^$9(B. + + IRB.conf[:IRB_NAME]="irb" + IRB.conf[:MATH_MODE]=false + IRB.conf[:USE_TRACER]=false + IRB.conf[:USE_LOADER]=false + IRB.conf[:IGNORE_SIGINT]=true + IRB.conf[:IGNORE_EOF]=false + IRB.conf[:INSPECT_MODE]=nil + IRB.conf[:IRB_RC] = nil + IRB.conf[:BACK_TRACE_LIMIT]=16 + IRB.conf[:USE_LOADER] = false + IRB.conf[:USE_READLINE] = nil + IRB.conf[:USE_TRACER] = false + IRB.conf[:IGNORE_SIGINT] = true + IRB.conf[:IGNORE_EOF] = false + IRB.conf[:PROMPT_MODE] = :DEFALUT + IRB.conf[:PROMPT] = {...} + IRB.conf[:DEBUG_LEVEL]=0 + IRB.conf[:VERBOSE]=true + +== $B%W%m%s%W%H$N@_Dj(B + +$B%W%m%s%W%H$r%+%9%?%^%$%:$7$?$$;~$K$O(B, + + IRB.conf[:PROMPT] + +$B$rMQ$$$^$9(B. $BNc$($P(B, .irbrc$B$NCf$G2<$N$h$&$J<0$r5-=R$7$^$9(B: + + IRB.conf[:PROMPT][:MY_PROMPT] = { # $B%W%m%s%W%H%b!<%I$NL>A0(B + :PROMPT_I => nil, # $BDL>o$N%W%m%s%W%H(B + :PROMPT_S => nil, # $BJ8;zNs$J$I$N7QB39T$N%W%m%s%W%H(B + :PROMPT_C => nil, # $B<0$,7QB3$7$F$$$k;~$N%W%m%s%W%H(B + :RETURN => " ==>%s\n" # $B%j%?!<%s;~$N%W%m%s%W%H(B + } + +$B%W%m%s%W%H%b!<%I$r;XDj$7$?$$;~$K$O(B, + + irb --prompt my-prompt + +$B$G$=$N%W%m%s%W%H%b!<%I$G5/F0$5$l$^$9(B. $B$^$?$O(B, .irbrc$B$K2<<0$r5-=R$7$F$b(B +OK$B$G$9(B. + + IRB.conf[:PROMPT_MODE] = :MY_PROMPT + +PROMPT_I, PROMPT_S, PROMPT_C$B$O(B, $B%U%)!<%^%C%H$r;XDj$7$^$9(B. + + %N $B5/F0$7$F$$$k%3%^%s%IL>$,=PNO$5$l$k(B. + %m main$B%*%V%8%'%/%H(B(self)$B$,(Bto_s$B$G=PNO$5$l$k(B. + %M main$B%*%V%8%'%/%H(B(self)$B$,(Binspect$B$5$l$F=PNO$5$l$k(B. + %l $BJ8;zNsCf$N%?%$%W$rI=$9(B(", ', /, ], `]'$B$O(B%w$B$NCf$N;~(B) + %NNi $B%$%s%G%s%H$N%l%Y%k$rI=$9(B. NN$B$O?t;z$,F~$j(Bprintf$B$N(B%NNd$B$HF1$8(B. $B>J(B + $BN,2DG=(B + %NNn $B9THV9f$rI=$7$^$9(B. + %% % + +$BNc$($P(B, $B%G%U%)%k%H$N%W%m%s%W%H%b!<%I$O(B: + + IRB.conf[:PROMPT_MODE][:DEFAULT] = { + :PROMPT_I => "%N(%m):%03n:%i> ", + :PROMPT_S => "%N(%m):%03n:%i%l ", + :PROMPT_C => "%N(%m):%03n:%i* ", + :RETURN => "%s\n" + } + +$B$H$J$C$F$$$^$9(B. + +RETURN$B$O(B, $B8=:_$N$H$3$m(Bprintf$B7A<0$G$9(B. $B>-Mh;EMM$,JQ$o$k$+$bCN$l$^$;$s(B. + +== $B%5%V(Birb$B$N@_Dj(B + +$B%3%^%s%I%i%$%s%*%W%7%g%s$*$h$S(BIRB.conf$B$O(B($B%5%V(B)irb$B5/F0;~$N%G%U%)%k%H$N(B +$B@_Dj$r7h$a$k$b$N$G(B, `5. $B%3%^%s%I(B'$B$K$"$k(Bconf$B$G8DJL$N(B($B%5%V(B)irb$B$N@_Dj$,$G(B +$B$-$k$h$&$K$J$C$F$$$^$9(B. + +IRB.conf[:IRB_RC]$B$K(Bproc$B$,@_Dj$5$l$F$$$k$H(B, $B%5%V(Birb$B$r5/F0$9$k;~$K$=$N(B +proc$B$r(Birb$B$N%3%s%F%-%9%H$r0z?t$H$7$F8F$S=P$7$^$9(B. $B$3$l$K$h$C$F8DJL$N%5(B +$B%V(Birb$B$4$H$K@_Dj$rJQ$($k$3$H$,$G$-$k$h$&$K$J$j$^$9(B. + + += $B%3%^%s%I(B + +irb$B3HD%%3%^%s%I$O(B, $B4JC1$JL>A0$HF,$K(B`irb_'$B$r$D$1$?L>A0$HN>J}Dj5A$5$l$F(B +$B$$$^$9(B. $B$3$l$O(B, $B4JC1$JL>A0$,(Boverride$B$5$l$?;~$N$?$a$G$9(B. + +--- exit, quit, irb_exit + $B=*N;$9$k(B. + $B%5%V(Birb$B$N>l9g(B, $B$=$N%5%V(Birb$B$r=*N;$9$k(B. + cb$B$7$F$$$k>l9g(B, $B$=$N%P%$%s%G%#%s%0$N%b!<%I$r=*N;$9$k(B. + +--- conf, irb_context + irb$B$N8=:_$N@_Dj$rI=<($9$k(B. $B@_Dj$NJQ99$O(B, conf$B$K%a%C%;!<%8$rAw$k$3(B + $B$H$K$h$C$F9T$J$($k(B. + +--- conf.back_trace_limit + $B%P%C%/%H%l!<%9I=<($r%P%C%/%H%l!<%9$NF,$+$i(Bn, $B8e$m$+$i(Bn$B$@$19T$J$&(B. + $B%G%U%)%k%H$O(B16 + +--- conf.debug_level = N + irb$BMQ$N%G%P%C%0%l%Y%k$N@_Dj(B + +--- conf.ignore_eof = true/false + ^D$B$,F~NO$5$l$?;~$NF0:n$r@_Dj$9$k(B. true$B$N;~$O(B^D$B$rL5;k$9$k(B, false$B$N(B + $B;~$O(Birb$B$r=*N;$9$k(B. + +--- conf.ignore_sigint= true/false + ^C$B$,F~NO$5$l$?;~$NF0:n$r@_Dj$9$k(B. false$B;~$O(B, irb$B$r=*N;$9$k(B. true$B$N(B + $B;~$NF0:n$O0J2<$N$h$&$K$J$k(B: + $BF~NOCf(B: $B$3$l$^$GF~NO$7$?$b$N$r%-%c%s%;%k$7%H%C%W%l%Y%k$KLa$k(B. + $B<B9TCf(B: $B<B9T$rCf;_$9$k(B. + +--- conf.inf_ruby_mode = true/false + inf-ruby-mode$BMQ$N%W%m%s%W%HI=<($r9T$J$&(B. $B%G%U%)%k%H$O(Bfalse. + +--- conf.inspect_mode = true/false/nil + $B%$%s%9%Z%/%H%b!<%I$r@_Dj$9$k(B. + true: $B%$%s%9%Z%/%H$7$FI=<($9$k(B. + false: $BDL>o$N(Bprint$B$GI=<($9$k(B. + nil: $BDL>o%b!<%I$G$"$l$P(B, inspect mode$B$H$J$j(B, math$B%b!<%I$N;~$O(B, non + inspect mode$B$H$J$k(B. + +--- conf.irb_level + $B;2>H$N$_(B. irb$B$,2?CJ(Bcb$B$7$F$$$k$+(B? + +--- conf.math_mode + $B;2>H$N$_(B. bc$B%b!<%I(B($BJ,?t(B, $B9TNs$N7W;;$,$G$-$^$9(B)$B$+$I$&$+(B? + +--- conf.use_loader = true/false + load/require$B;~$K(Birb$B$N(Bfile$BFI$_9~$_5!G=$rMQ$$$k%b!<%I$N%9%$%C%A(B($B%G%U%)(B + $B%k%H$OMQ$$$J$$(B). $B$3$N%b!<%I$O(BIRB$BA4BN$KH?1G$5$l$k(B. + +--- conf.prompt_c + if$B$ND>8e$J$I(B, $B9T$,7QB3$7$F$$$k;~$N%W%m%s%W%H(B. + +--- conf.prompt_i + $BDL>o$N%W%m%s%W%H(B. + +--- conf.prompt_s + $BJ8;zNsCf$J$I$rI=$9%W%m%s%W%H(B. + +--- conf.rc + ~/.irbrc$B$rFI$_9~$s$@$+$I$&$+(B? + +--- conf.use_prompt = true/false + $B%W%m%s%W%HI=<($9$k$+$I$&$+(B? $B%G%U%)%k%H$G$O%W%m%s%W%H$rI=<($9$k(B. + +--- conf.use_readline = true/false/nil + readline$B$r;H$&$+$I$&$+(B? + true: readline$B$r;H$&(B. + false: readline$B$r;H$o$J$$(B. + nil: ($B%G%U%)%k%H(B)inf-reuby-mode$B0J30$G(Breadline$B%i%$%V%i%j$rMxMQ$7$h(B + $B$&$H$9$k(B. + +--- conf.verbose=T/F + irb$B$+$i$$$m$$$m$J%a%C%;!<%8$r=PNO$9$k$+(B? + +--- cb, irb_change_binding [obj] + $B%m!<%+%kJQ?t$N%9%3!<%W$,0c$&?7$?$J(Bbinding$B$K0\$k(B. obj$B$,;XDj$5$l$?(B + $B;~$O(B, $B$=$N(Bobj$B$r(Bself$B$H$9$k(B. + +--- irb [obj] + $B%5%V(Birb$B$rN)$A$"$2$k(B. obj$B$,;XDj$5$l$?;~$O(B, $B$=$N(Bobj$B$r(Bself$B$H$9$k(B. + +--- jobs, irb_jobs + $B%5%V(Birb$B$N%j%9%H(B + +--- fg n, irb_fg n + $B;XDj$7$?%5%V(Birb$B$K%9%$%C%A$9$k(B. n$B$O(B, $B<!$N$b$N$r;XDj$9$k(B. + + irb$BHV9f(B + $B%9%l%C%I(B + irb$B%*%V%8%'%/%H(B + self(irb obj$B$G5/F0$7$?;~$N(Bobj) + +--- kill n, irb_kill n + $B%5%V(Birb$B$r(Bkill$B$9$k(B. n$B$O(Bfg$B$HF1$8(B. + + += $B%7%9%F%`JQ?t(B + + _ $BA0$N7W;;$N<B9T7k2L$r3P$($F$$$k(B($B%m!<%+%kJQ?t(B). + += $B;HMQNc(B + +$B0J2<$N$h$&$J46$8$G$9(B. + + dim% ruby irb.rb + irb(main):001:0> irb # $B%5%V(Birb$B$NN)$A$"$2(B + irb#1(main):001:0> jobs # $B%5%V(Birb$B$N%j%9%H(B + #0->irb on main (#<Thread:0x400fb7e4> : stop) + #1->irb#1 on main (#<Thread:0x40125d64> : running) + nil + irb#1(main):002:0> fg 0 # job$B$N%9%$%C%A(B + nil + irb(main):002:0> class Foo;end + nil + irb(main):003:0> irb Foo # Foo$B$r%3%s%F%-%9%H$7$F(Birb + # $BN)$A$"$2(B + irb#2(Foo):001:0> def foo # Foo#foo$B$NDj5A(B + irb#2(Foo):002:1> print 1 + irb#2(Foo):003:1> end + nil + irb#2(Foo):004:0> fg 0 # job$B$r%9%$%C%A(B + nil + irb(main):004:0> jobs # job$B$N%j%9%H(B + #0->irb on main (#<Thread:0x400fb7e4> : running) + #1->irb#1 on main (#<Thread:0x40125d64> : stop) + #2->irb#2 on Foo (#<Thread:0x4011d54c> : stop) + nil + irb(main):005:0> Foo.instance_methods # Foo#foo$B$,$A$c$s$HDj5A$5(B + # $B$l$F$$$k(B + ["foo"] + irb(main):006:0> fg 2 # job$B$r%9%$%C%A(B + nil + irb#2(Foo):005:0> def bar # Foo#bar$B$rDj5A(B + irb#2(Foo):006:1> print "bar" + irb#2(Foo):007:1> end + nil + irb#2(Foo):010:0> Foo.instance_methods + ["bar", "foo"] + irb#2(Foo):011:0> fg 0 + nil + irb(main):007:0> f = Foo.new + #<Foo:0x4010af3c> + irb(main):008:0> irb f # Foo$B$N%$%s%9%?%s%9$G(Birb$B$r(B + # $BN)$A$"$2$k(B. + irb#3(#<Foo:0x4010af3c>):001:0> jobs + #0->irb on main (#<Thread:0x400fb7e4> : stop) + #1->irb#1 on main (#<Thread:0x40125d64> : stop) + #2->irb#2 on Foo (#<Thread:0x4011d54c> : stop) + #3->irb#3 on #<Foo:0x4010af3c> (#<Thread:0x4010a1e0> : running) + nil + irb#3(#<Foo:0x4010af3c>):002:0> foo # f.foo$B$N<B9T(B + nil + irb#3(#<Foo:0x4010af3c>):003:0> bar # f.bar$B$N<B9T(B + barnil + irb#3(#<Foo:0x4010af3c>):004:0> kill 1, 2, 3# job$B$N(Bkill + nil + irb(main):009:0> jobs + #0->irb on main (#<Thread:0x400fb7e4> : running) + nil + irb(main):010:0> exit # $B=*N;(B + dim% + += $B;HMQ>e$N@)8B(B + +irb$B$O(B, $BI>2A$G$-$k;~E@(B($B<0$,JD$8$?;~E@(B)$B$G$NC`<!<B9T$r9T$J$$$^$9(B. $B$7$?$,$C(B +$B$F(B, ruby$B$rD>@\;H$C$?;~$H(B, $B<c430[$J$kF0:n$r9T$J$&>l9g$,$"$j$^$9(B. + +$B8=:_L@$i$+$K$J$C$F$$$kLdBjE@$r@bL@$7$^$9(B. + +== $B%m!<%+%kJQ?t$N@k8@(B + +ruby$B$G$O(B, $B0J2<$N%W%m%0%i%`$O%(%i!<$K$J$j$^$9(B. + + eval "foo = 0" + foo + -- + -:2: undefined local variable or method `foo' for #<Object:0x40283118> (NameError) + --- + NameError + +$B$H$3$m$,(B, irb$B$rMQ$$$k$H(B + + >> eval "foo = 0" + => 0 + >> foo + => 0 + +$B$H$J$j(B, $B%(%i!<$r5/$3$7$^$;$s(B. $B$3$l$O(B, ruby$B$,:G=i$K%9%/%j%W%HA4BN$r%3%s(B +$B%Q%$%k$7$F%m!<%+%kJQ?t$r7hDj$9$k$+$i$G$9(B. $B$=$l$KBP$7(B, irb$B$O<B9T2DG=$K(B +$B$J$k(B($B<0$,JD$8$k(B)$B$H<+F0E*$KI>2A$7$F$$$k$+$i$G$9(B. $B>e5-$NNc$G$O(B, + + evel "foo = 0" + +$B$r9T$J$C$?;~E@$GI>2A$r9T$J$$(B, $B$=$N;~E@$GJQ?t$,Dj5A$5$l$k$?$a(B, $B<!<0$G(B +$BJQ?t(Bfoo$B$ODj5A$5$l$F$$$k$+$i$G$9(B. + +$B$3$N$h$&$J(Bruby$B$H(Birb$B$NF0:n$N0c$$$r2r7h$7$?$$>l9g$O(B, begin...end$B$G3g$C$F(B +$B%P%C%AE*$K<B9T$7$F2<$5$$(B: + + >> begin + ?> eval "foo = 0" + >> foo + >> end + NameError: undefined local variable or method `foo' for #<Object:0x4013d0f0> + (irb):3 + (irb_local_binding):1:in `eval' + +== $B%R%"%I%-%e%a%s%H(B + +$B8=:_$N$H$3$m%R%"%I%-%e%a%s%H$N<BAu$OIT40A4$G$9(B. + +== $B%7%s%\%k(B + +$B%7%s%\%k$G$"$k$+$I$&$+$NH=CG$r4V0c$($k$3$H$,$"$j$^$9(B. $B6qBNE*$K$O<0$,40N;(B +$B$7$F$$$k$N$K7QB39T$H8+$J$9$3$H$,$"$j$^$9(B. + +==end + +% Begin Emacs Environment +% Local Variables: +% mode: text +% comment-column: 0 +% comment-start: "%" +% comment-end: "\n" +% End: +% + diff --git a/lib/irb.rb b/lib/irb.rb new file mode 100644 index 000000000..bfeb3f8be --- /dev/null +++ b/lib/irb.rb @@ -0,0 +1,317 @@ +# +# irb.rb - irb main module +# $Release Version: 0.7.3 $ +# $Revision$ +# $Date$ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# -- +# +# +# +require "e2mmap" + +require "irb/init" +require "irb/context" +require "irb/extend-command" +require "irb/workspace" + +require "irb/ruby-lex" +require "irb/input-method" +require "irb/locale" + +STDOUT.sync = true + +module IRB + @RCS_ID='-$Id$-' + + class Abort < Exception;end + + # + @CONF = {} + + def IRB.conf + @CONF + end + + # IRB version method + def IRB.version + if v = @CONF[:VERSION] then return v end + + require "irb/version" + rv = @RELEASE_VERSION.sub(/\.0/, "") + @CONF[:VERSION] = format("irb %s(%s)", rv, @LAST_UPDATE_DATE) + end + + # initialize IRB and start TOP_LEVEL irb + # (JP: IRB$B=i4|2=$H%H%C%W%l%Y%k(Birb$B5/F0(B) + def IRB.start(ap_path = nil) + $0 = File::basename(ap_path, ".rb") if ap_path + + IRB.initialize(ap_path) + IRB.parse_opts + IRB.load_modules + + if @CONF[:SCRIPT] + irb = Irb.new(nil, @CONF[:SCRIPT]) + else + irb = Irb.new + end + + @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC] + @CONF[:MAIN_CONTEXT] = irb.context + + trap("SIGINT") do + irb.signal_handle + end + + catch(:IRB_EXIT) do + irb.eval_input + end + print "\n" + end + + def IRB.irb_exit(irb, ret) + throw :IRB_EXIT, ret + end + + def IRB.irb_abort(irb, exception = Abort) + if defined? Thread + irb.context.thread.raise exception, "abort then interrupt!!" + else + raise exception, "abort then interrupt!!" + end + end + + # + # irb interpriter main routine + # (JP: irb$B%$%s%?%W%j%?K\BN(B) + # + class Irb + def initialize(workspace = nil, input_method = nil) + @context = Context.new(self, workspace, input_method) + @context.main.extend ExtendCommand + @signal_status = :IN_IRB + + @scanner = RubyLex.new + @scanner.exception_on_syntax_error = false + end + attr_reader :context + attr_accessor :scanner + + def eval_input + @scanner.set_input(@context.io) do + signal_status(:IN_INPUT) do + unless l = @context.io.gets + if @context.ignore_eof? and @context.io.readable_atfer_eof? + l = "\n" + if @context.verbose? + printf "Use \"exit\" to leave %s\n", @context.ap_name + end + end + end + l + end + end + + @scanner.set_prompt do + |ltype, indent, continue, line_no| + if ltype + f = @context.prompt_s + elsif continue + f = @context.prompt_c + else @context.prompt_i + f = @context.prompt_i + end + f = "" unless f + @context.io.prompt = p = prompt(f, ltype, indent, line_no) + if @context.auto_indent_mode + unless ltype + ind = prompt(@context.prompt_i, ltype, indent, line_no).size + + indent * 2 - p.size + ind += 2 if continue + @context.io.prompt = p + " " * ind if ind > 0 + end + end + end + + @scanner.each_top_level_statement do + |line, line_no| + signal_status(:IN_EVAL) do + begin + trace_in do + @context._ = @context.workspace.evaluate(line, + @context.irb_path, + line_no) +# @context._ = irb_eval(line, @context.bind, @context.irb_path, line_no) + end + + if @context.inspect? + printf @context.return_format, @context._.inspect + else + printf @context.return_format, @context._ + end + rescue StandardError, ScriptError, Abort + $! = RuntimeError.new("unknown exception raised") unless $! + print $!.type, ": ", $!, "\n" + if $@[0] =~ /irb(2)?(\/.*|-.*|\.rb)?:/ && $!.type.to_s !~ /^IRB/ + irb_bug = true + else + irb_bug = false + end + + messages = [] + lasts = [] + levels = 0 + for m in $@ + m = @context.workspace.filter_backtrace(m) unless irb_bug + if m + if messages.size < @context.back_trace_limit + messages.push "\tfrom "+m + else + lasts.push "\tfrom "+m + if lasts.size > @context.back_trace_limit + lasts.shift + levels += 1 + end + end + end + end + print messages.join("\n"), "\n" + unless lasts.empty? + printf "... %d levels...\n", levels if levels > 0 + print lasts.join("\n") + end + print "Maybe IRB bug!!\n" if irb_bug + end + end + end + end + +# def irb_eval(line, bind, path, line_no) +# id, str = catch(:IRB_TOPLEVEL_EVAL){ +# return eval(line, bind, path, line_no) +# } +# case id +# when :EVAL_TOPLEVEL +# eval(str, bind, "(irb_internal)", 1) +# when :EVAL_CONTEXT +# @context.instance_eval(str) +# else +# IRB.fail IllegalParameter +# end +# end + + def signal_handle + unless @context.ignore_sigint? + print "\nabort!!\n" if @context.verbose? + exit + end + + case @signal_status + when :IN_INPUT + print "^C\n" + @scanner.initialize_input + print @context.io.prompt + when :IN_EVAL + IRB.irb_abort(self) + when :IN_LOAD + IRB.irb_abort(self, LoadAbort) + when :IN_IRB + # ignore (JP: $B2?$b$7$J$$(B.) + else + # ignore (JP: $B$=$NB>$N>l9g$b2?$b$7$J$$(B.) + end + end + + def signal_status(status) + return yield if @signal_status == :IN_LOAD + + signal_status_back = @signal_status + @signal_status = status + begin + yield + ensure + @signal_status = signal_status_back + end + end + + def trace_in + Tracer.on if @context.use_tracer? + begin + yield + ensure + Tracer.off if @context.use_tracer? + end + end + + def prompt(prompt, ltype, indent, line_no) + p = prompt.dup + p.gsub!(/%([0-9]+)?([a-zA-Z])/) do + case $2 + when "N" + @context.irb_name + when "m" + @context.main.to_s + when "M" + @context.main.inspect + when "l" + ltype + when "i" + if $1 + format("%" + $1 + "d", indent) + else + indent.to_s + end + when "n" + if $1 + format("%" + $1 + "d", line_no) + else + line_no.to_s + end + when "%" + "%" + end + end + p + end + + def inspect + ary = [] + for iv in instance_variables + case iv + when "@signal_status" + ary.push format("%s=:%s", iv, @signal_status.id2name) + when "@context" + ary.push format("%s=%s", iv, eval(iv).__to_s__) + else + ary.push format("%s=%s", iv, eval(iv)) + end + end + format("#<%s: %s>", type, ary.join(", ")) + end + end + + # Singleton method + def @CONF.inspect + IRB.version unless self[:VERSION] + + array = [] + for k, v in sort{|a1, a2| a1[0].id2name <=> a2[0].id2name} + case k + when :MAIN_CONTEXT + next + when :PROMPT + s = v.collect{ + |kk, vv| + ss = vv.collect{|kkk, vvv| ":#{kkk.id2name}=>#{vvv.inspect}"} + format(":%s=>{%s}", kk.id2name, ss.join(", ")) + } + array.push format("CONF[:%s]={%s}", k.id2name, s.join(", ")) + else + array.push format("CONF[:%s]=%s", k.id2name, v.inspect) + end + end + array.join("\n") + end +end diff --git a/lib/irb/context.rb b/lib/irb/context.rb new file mode 100644 index 000000000..8fa9de63a --- /dev/null +++ b/lib/irb/context.rb @@ -0,0 +1,290 @@ +# +# irb/context.rb - irb context +# $Release Version: 0.7.3$ +# $Revision$ +# $Date$ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# -- +# +# +# +module IRB + class Context + # + # Arguments: + # input_method: nil -- stdin or readline + # String -- File + # other -- using this as InputMethod + # + def initialize(irb, workspace = nil, input_method = nil) + @irb = irb + if workspace + @workspace = workspace + else + @workspace = WorkSpace.new unless workspace + end + @thread = Thread.current if defined? Thread + @irb_level = 0 + + # copy of default configuration + # (JP: $B%G%U%)%k%H%3%s%U%#%.%e%l!<%7%g%s$N%3%T!<(B) + @ap_name = IRB.conf[:AP_NAME] + @rc = IRB.conf[:RC] + @load_modules = IRB.conf[:LOAD_MODULES] + + self.math_mode = IRB.conf[:MATH_MODE] + @use_readline = IRB.conf[:USE_READLINE] + @inspect_mode = IRB.conf[:INSPECT_MODE] + self.use_tracer = IRB.conf[:USE_TRACER] +# @use_loader = IRB.conf[:USE_LOADER] + + self.prompt_mode = IRB.conf[:PROMPT_MODE] + + @ignore_sigint = IRB.conf[:IGNORE_SIGINT] + @ignore_eof = IRB.conf[:IGNORE_EOF] + + @back_trace_limit = IRB.conf[:BACK_TRACE_LIMIT] + + debug_level = IRB.conf[:DEBUG_LEVEL] + @verbose = IRB.conf[:VERBOSE] + + @tracer_initialized = false + + if IRB.conf[:SINGLE_IRB] or !defined?(JobManager) + @irb_name = IRB.conf[:IRB_NAME] + else + @irb_name = "irb#"+IRB.JobManager.n_jobs.to_s + end + @irb_path = "(" + @irb_name + ")" + + case input_method + when nil + if (use_readline.nil? && IRB.conf[:PROMPT_MODE] != :INF_RUBY || + use_readline?) + @io = ReadlineInputMethod.new + else + @io = StdioInputMethod.new + end + when String + @io = FileInputMethod.new(input_method) + @irb_name = File.basename(input_method) + @irb_path = input_method + else + @io = input_method + end + end + + def main + @workspace.main + end + + attr_accessor :workspace + attr_reader :thread + attr_accessor :io + + attr_reader :_ + + attr_accessor :irb + attr_accessor :ap_name + attr_accessor :rc + attr_accessor :load_modules + attr_accessor :irb_name + attr_accessor :irb_path + + attr_accessor :math_mode + attr_accessor :use_readline + attr_reader :inspect_mode + attr_reader :use_tracer +# attr :use_loader + + attr_reader :debug_level + attr_accessor :verbose + + attr_reader :prompt_mode + attr_accessor :prompt_i + attr_accessor :prompt_s + attr_accessor :prompt_c + attr_accessor :auto_indent_mode + attr_accessor :return_format + + attr_accessor :ignore_sigint + attr_accessor :ignore_eof + + attr_accessor :back_trace_limit + +# alias use_loader? use_loader + alias use_tracer? use_tracer + alias use_readline? use_readline + alias rc? rc + alias math? math_mode + alias verbose? verbose + alias ignore_sigint? ignore_sigint + alias ignore_eof? ignore_eof + + def _=(value) + @_ = value + @workspace.evaluate "_ = IRB.conf[:MAIN_CONTEXT]._" + end + + def irb_name + if @irb_level == 0 + @irb_name + elsif @irb_name =~ /#[0-9]*$/ + @irb_name + "." + @irb_level.to_s + else + @irb_name + "#0." + @irb_level.to_s + end + end + + def prompt_mode=(mode) + @prompt_mode = mode + pconf = IRB.conf[:PROMPT][mode] + @prompt_i = pconf[:PROMPT_I] + @prompt_s = pconf[:PROMPT_S] + @prompt_c = pconf[:PROMPT_C] + @return_format = pconf[:RETURN] + if ai = pconf.include?(:AUTO_INDENT) + @auto_indent_mode = ai + else + @auto_indent_mode = IRB.conf[:AUTO_INDENT] + end + end + + def inspect? + @inspect_mode.nil? && !@math_mode or @inspect_mode + end + + def file_input? + @io.type == FileInputMethod + end + + def use_tracer=(opt) + if opt + IRB.initialize_tracer + unless @tracer_initialized + Tracer.set_get_line_procs(@irb_path) { + |line_no| + @io.line(line_no) + } + @tracer_initialized = true + end + elsif !opt && @use_tracer + Tracer.off + end + @use_tracer=opt + end + + def use_loader + IRB.conf[:USE_LOADER] + end + + def use_loader=(opt) + IRB.conf[:USE_LOADER] = opt + if opt + IRB.initialize_loader + end + print "Switch to load/require#{unless use_loader; ' non';end} trace mode.\n" if verbose? + opt + end + + def inspect_mode=(opt) + if opt + @inspect_mode = opt + else + @inspect_mode = !@inspect_mode + end + print "Switch to#{unless @inspect_mode; ' non';end} inspect mode.\n" if verbose? + @inspect_mode + end + + def math_mode=(opt) + if @math_mode == true && opt == false + IRB.fail CantRetuenNormalMode + return + end + + @math_mode = opt + if math_mode + IRB.initialize_mathn + main.instance_eval("include Math") + print "start math mode\n" if verbose? + end + end + + def use_readline=(opt) + @use_readline = opt + print "use readline module\n" if @use_readline + end + + def debug_level=(value) + @debug_level = value + RubyLex.debug_level = value + SLex.debug_level = value + end + + def debug? + @debug_level > 0 + end + + def change_binding(*_main) + back = @workspace + @workspace = WorkSpace.new(*_main) + unless _main.empty? + begin + main.extend ExtendCommand + rescue + print "can't change binding to: ", main.inspect, "\n" + @workspace = back + return nil + end + end + @irb_level += 1 + begin + catch(:SU_EXIT) do + @irb.eval_input + end + ensure + @irb_level -= 1 + @workspace = back + end + end + alias change_workspace change_binding + + + alias __exit__ exit + def exit(ret = 0) + if @irb_level == 0 + IRB.irb_exit(@irb, ret) + else + throw :SU_EXIT, ret + end + end + + NOPRINTING_IVARS = ["@_"] + NO_INSPECTING_IVARS = ["@irb", "@io"] + IDNAME_IVARS = ["@prompt_mode"] + + alias __inspect__ inspect + def inspect + array = [] + for ivar in instance_variables.sort{|e1, e2| e1 <=> e2} + name = ivar.sub(/^@(.*)$/){$1} + val = instance_eval(ivar) + case ivar + when *NOPRINTING_IVARS + next + when *NO_INSPECTING_IVARS + array.push format("conf.%s=%s", name, val.to_s) + when *IDNAME_IVARS + array.push format("conf.%s=:%s", name, val.id2name) + else + array.push format("conf.%s=%s", name, val.inspect) + end + end + array.join("\n") + end + alias __to_s__ to_s + alias to_s inspect + end +end diff --git a/lib/irb/extend-command.rb b/lib/irb/extend-command.rb new file mode 100644 index 000000000..bc657520a --- /dev/null +++ b/lib/irb/extend-command.rb @@ -0,0 +1,127 @@ +# +# irb/extend-command.rb - irb command extend +# $Release Version: 0.7.3$ +# $Revision$ +# $Date$ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# -- +# +# +# +module IRB + # + # IRB extended command + # (JP: IRB$B3HD%%3%^%s%I(B) + # + module ExtendCommand +# include Loader + + def irb_exit(ret = 0) + irb_context.exit(ret) + end + alias irb_quit irb_exit + + def irb_fork(&block) + pid = send ExtendCommand.irb_original_method_name("fork") + unless pid + class<<self + alias_method :exit, ExtendCommand.irb_original_method_name('exit') + end + if iterator? + begin + yield + ensure + exit + end + end + end + pid + end + + def irb_change_binding(*main) + irb_context.change_binding(*main) + end + alias irb_change_workspace irb_change_binding + + def irb_source(file) + irb_context.source(file) + end + + def irb(*obj) + require "irb/multi-irb" + IRB.irb(nil, *obj) + end + + def irb_context + IRB.conf[:MAIN_CONTEXT] + end + + def irb_jobs + require "irb/multi-irb" + IRB.JobManager + end + + def irb_fg(key) + require "irb/multi-irb" + IRB.JobManager.switch(key) + end + + def irb_kill(*keys) + require "irb/multi-irb" + IRB.JobManager.kill(*keys) + end + + # extend command functions + def ExtendCommand.extend_object(obj) + super + unless (class<<obj;ancestors;end).include?(ExtendCommand) + obj.install_aliases + end + end + + OVERRIDE_NOTHING = 0 + OVERRIDE_PRIVATE_ONLY = 0x01 + OVERRIDE_ALL = 0x02 + + def install_aliases(override = OVERRIDE_NOTHING) + + install_alias_method(:exit, :irb_exit, override | OVERRIDE_PRIVATE_ONLY) + install_alias_method(:quit, :irb_quit, override | OVERRIDE_PRIVATE_ONLY) + install_alias_method(:fork, :irb_fork, override | OVERRIDE_PRIVATE_ONLY) + install_alias_method(:kill, :irb_kill, override | OVERRIDE_PRIVATE_ONLY) + + install_alias_method(:irb_cb, :irb_change_binding, override) + install_alias_method(:irb_ws, :irb_change_workspace, override) + install_alias_method(:source, :irb_source, override) + install_alias_method(:conf, :irb_context, override) + install_alias_method(:jobs, :irb_jobs, override) + install_alias_method(:fg, :irb_fg, override) + end + + # override = {OVERRIDE_NOTHING, OVERRIDE_PRIVATE_ONLY, OVERRIDE_ALL} + def install_alias_method(to, from, override = OVERRIDE_NOTHING) + to = to.id2name unless to.kind_of?(String) + from = from.id2name unless from.kind_of?(String) + + if override == OVERRIDE_ALL or + (override == OVERRIDE_PRIVATE_ONLY) && !respond_to?(to) or + (override == OVERRIDE_NOTHING) && !respond_to?(to, true) + target = self + (class<<self;self;end).instance_eval{ + if target.respond_to?(to, true) && + !target.respond_to?(ExtendCommand.irb_original_method_name(to), true) + alias_method(ExtendCommand.irb_original_method_name(to), to) + end + alias_method to, from + } + else + print "irb: warn: can't alias #{to} from #{from}.\n" + end + end + + def self.irb_original_method_name(method_name) + "irb_" + method_name + "_org" + end + end +end diff --git a/lib/irb/help.rb b/lib/irb/help.rb new file mode 100644 index 000000000..0821f68d1 --- /dev/null +++ b/lib/irb/help.rb @@ -0,0 +1,33 @@ +# +# irb/help.rb - print usase module +# $Release Version: 0.7.3$ +# $Revision$ +# $Date$ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# -- +# +# +# + +module IRB + def IRB.print_usage + lc = IRB.conf[:LC_MESSAGES] + path = lc.find("irb/help-message") + space_line = false + File.foreach(path) do + |l| + if /^\s*$/ =~ l + lc.puts l unless space_line + space_line = true + next + end + space_line = false + + l.sub!(/#.*$/, "") + next if /^\s*$/ =~ l + lc.puts l + end + end +end + diff --git a/lib/irb/init.rb b/lib/irb/init.rb new file mode 100644 index 000000000..abfd9cdc2 --- /dev/null +++ b/lib/irb/init.rb @@ -0,0 +1,238 @@ +# +# irb/init.rb - irb initialize module +# $Release Version: 0.7.3$ +# $Revision$ +# $Date$ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# -- +# +# +# + +module IRB + + # initialize config + # (JP: config$B$N=i4|2=(B) + def IRB.initialize(ap_path) + IRB.init_config(ap_path) + IRB.init_error + IRB.run_config + end + + # @CONF default setting + def IRB.init_config(ap_path) + # class instance variables + @TRACER_INITIALIZED = false + @MATHN_INITIALIZED = false + + # default configurations + # (JP: $B%G%U%)%k%H%3%s%U%#%.%e%l!<%7%g%s(B) + unless ap_path and @CONF[:AP_NAME] + ap_path = File.join(File.dirname(File.dirname(__FILE__)), "irb.rb") + end + @CONF[:AP_NAME] = File::basename(ap_path, ".rb") + + @CONF[:IRB_NAME] = "irb" + @CONF[:IRB_LIB_PATH] = File.dirname(__FILE__) + + @CONF[:RC] = true + @CONF[:LOAD_MODULES] = [] + @CONF[:IRB_RC] = nil + + @CONF[:MATH_MODE] = false + @CONF[:USE_READLINE] = false unless defined?(ReadlineInputMethod) + @CONF[:INSPECT_MODE] = nil + @CONF[:USE_TRACER] = false + @CONF[:USE_LOADER] = false + @CONF[:IGNORE_SIGINT] = true + @CONF[:IGNORE_EOF] = false + + @CONF[:BACK_TRACE_LIMIT] = 16 + + @CONF[:PROMPT] = { + :NULL => { + :PROMPT_I => nil, + :PROMPT_S => nil, + :PROMPT_C => nil, + :RETURN => "%s\n" + }, + :DEFAULT => { + :PROMPT_I => "%N(%m):%03n:%i> ", + :PROMPT_S => "%N(%m):%03n:%i%l ", + :PROMPT_C => "%N(%m):%03n:%i* ", + :RETURN => "%s\n" + }, + :SIMPLE => { + :PROMPT_I => ">> ", + :PROMPT_S => nil, + :PROMPT_C => "?> ", + :RETURN => "=> %s\n" + }, + :INF_RUBY => { + :PROMPT_I => "%N(%m):%03n:%i> ", + :PROMPT_S => nil, + :PROMPT_C => nil, + :RETURN => "%s\n", + :AUTO_INDENT => true + }, + :XMP => { + :PROMPT_I => nil, + :PROMPT_S => nil, + :PROMPT_C => nil, + :RETURN => " ==>%s\n" + } + } + + @CONF[:PROMPT_MODE] = :DEFAULT + @CONF[:AUTO_INDENT] = false + + @CONF[:CONTEXT_MODE] = 3 # use binding in function on TOPLEVEL_BINDING + @CONF[:SINGLE_IRB] = false + +# @CONF[:LC_MESSAGES] = "en" + @CONF[:LC_MESSAGES] = Locale.new + + @CONF[:DEBUG_LEVEL] = 1 + @CONF[:VERBOSE] = true + end + + def IRB.init_error + @CONF[:LC_MESSAGES].load("irb/error.rb") + end + + # option analyzing + # (JP: $B%*%W%7%g%s2r@O(B) + def IRB.parse_opts + while opt = ARGV.shift + case opt + when "-f" + opt = ARGV.shift + @CONF[:RC] = false + when "-m" + @CONF[:MATH_MODE] = true + when "-d" + $DEBUG = true + when "-r" + opt = ARGV.shift + @CONF[:LOAD_MODULES].push opt if opt + when "--inspect" + @CONF[:INSPECT_MODE] = true + when "--noinspect" + @CONF[:INSPECT_MODE] = false + when "--readline" + @CONF[:USE_READLINE] = true + when "--noreadline" + @CONF[:USE_READLINE] = false + + when "--prompt-mode", "--prompt" + prompt_mode = ARGV.shift.upcase.tr("-", "_").intern + IRB.fail(UndefinedPromptMode, + prompt_mode.id2name) unless @CONF[:PROMPT][prompt_mode] + @CONF[:PROMPT_MODE] = prompt_mode + when "--noprompt" + @CONF[:PROMPT_MODE] = :NULL + when "--inf-ruby-mode" + @CONF[:PROMPT_MODE] = :INF_RUBY + when "--sample-book-mode", "--simple-prompt" + @CONF[:PROMPT_MODE] = :SIMPLE + + when "--tracer" + @CONF[:USE_TRACER] = true + when "--back-trace-limit" + @CONF[:BACK_TRACE_LIMIT] = ARGV.shift.to_i + when "--context-mode" + @CONF[:CONTEXT_MODE] = ARGV.shift.to_i + when "--single-irb" + @CONF[:SINGLE_IRB] = true + when "--irb_debug" + @CONF[:DEBUG_LEVEL] = ARGV.shift.to_i + when "-v", "--version" + print IRB.version, "\n" + exit 0 + when "-h", "--help" + require "irb/help" + IRB.print_usage + exit 0 + when /^-/ + IRB.fail UnrecognizedSwitch, opt + else + @CONF[:USE_READLINE] = false + @CONF[:SCRIPT] = opt + $0 = opt + break + end + end + end + + # running config + def IRB.run_config + if @CONF[:RC] + rcs = [] + rcs.push File.expand_path("~/.irbrc") if ENV.key?("HOME") + rcs.push ".irbrc" + rcs.push "irb.rc" + rcs.push "_irbrc" + rcs.push "$irbrc" + catch(:EXIT) do + for rc in rcs + begin + load rc + throw :EXIT + rescue LoadError, Errno::ENOENT + rescue + print "load error: #{rc}\n" + print $!.type, ": ", $!, "\n" + for err in $@[0, $@.size - 2] + print "\t", err, "\n" + end + throw :EXIT + end + end + end + end + end + + # loading modules + def IRB.load_modules + for m in @CONF[:LOAD_MODULES] + begin + require m + rescue + print $@[0], ":", $!.type, ": ", $!, "\n" + end + end + end + + # initialize tracing function + # (JP: $B%H%l!<%5=i4|@_Dj(B) + def IRB.initialize_tracer + unless @TRACER_INITIALIZED + require("tracer") + Tracer.verbose = false + Tracer.add_filter { + |event, file, line, id, binding| + File::dirname(file) != @CONF[:IRB_LIB_PATH] + } + @TRACER_INITIALIZED = true + end + end + + # initialize mathn function + # (JP: mathn$B=i4|@_Dj(B) + def IRB.initialize_mathn + unless @MATHN_INITIALIZED + require "mathn" + @MATHN_INITIALIZED = true + end + end + + # initialize loader function + # (JP: loader$B=i4|@_Dj(B) + def IRB.initialize_loader + unless @LOADER_INITIALIZED + require "irb/loader" + @LOADER_INITIALIZED = true + end + end +end diff --git a/lib/irb/lc/error.rb b/lib/irb/lc/error.rb new file mode 100644 index 000000000..15f3cab83 --- /dev/null +++ b/lib/irb/lc/error.rb @@ -0,0 +1,30 @@ +# +# irb/lc/error.rb - +# $Release Version: 0.7.3$ +# $Revision$ +# $Date$ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# -- +# +# +# +require "e2mmap" + +module IRB + + # exceptions (JP: $BNc30Dj5A(B) + extend Exception2MessageMapper + def_exception :UnrecognizedSwitch, "Unrecognized switch: %s" + def_exception :NotImplementError, "Need to define `%s'" + def_exception :CantRetuenNormalMode, "Can't return normal mode." + def_exception :IllegalParameter, "Illegal parameter(%s)." + def_exception :IrbAlreadyDead, "Irb is already dead." + def_exception :IrbSwitchToCurrentThread, "Change to current thread." + def_exception :NoSuchJob, "No such job(%s)." + def_exception :CanNotGoMultiIrbMode, "Can't go multi irb mode." + def_exception :CanNotChangeBinding, "Can't change binding to (%s)." + def_exception :UndefinedPromptMode, "Undefined prompt mode(%s)." + +end + diff --git a/lib/irb/lc/help-message b/lib/irb/lc/help-message new file mode 100644 index 000000000..8a3d63803 --- /dev/null +++ b/lib/irb/lc/help-message @@ -0,0 +1,34 @@ +# +# irb/lc/help-message.rb - +# $Release Version: 0.7.3$ +# $Revision$ +# $Date$ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# -- +# +# +# +Usage: irb.rb [options] [programfile] [arguments] + -f suppress read ~/.irbrc + -m bc mode (load mathn, fraction or matrix are available) + -d set $DEBUG to true (same as `ruby -d') + -r load-module same as `ruby -r' + --inspect uses `inspect' for output (the default except bc mode) + --noinspect doesn't uses inspect for output + --readline uses Readline extension module + --noreadline doesn't use Readline extension module + --prompt prompt-mode + --prompt-mode prompt-mode + switches prompt mode. Pre-defined prompt modes are + `defalut', `simple', `xmp' and `inf-ruby' + --inf-ruby-mode uses prompt appreciate for inf-ruby-mode on emacs. + Suppresses --readline. + --simple-prompt simple prompt mode + --noprompt no prompt + --tracer display trace for each execution of commands. + --back-trace-limit n + displayes backtrace top n and tail n. The default + value is 16. + --irb_debug n sets internal debug level to n (It shouldn't be used) + -v, --version prints the version of irb diff --git a/lib/irb/lc/ja/error.rb b/lib/irb/lc/ja/error.rb new file mode 100644 index 000000000..1fa3ae328 --- /dev/null +++ b/lib/irb/lc/ja/error.rb @@ -0,0 +1,29 @@ +# +# irb/lc/ja/error.rb - +# $Release Version: 0.7.3$ +# $Revision$ +# $Date$ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# -- +# +# +# +require "e2mmap" + +module IRB + # exceptions (JP: $BNc30Dj5A(B) + extend Exception2MessageMapper + def_exception :UnrecognizedSwitch, '$B%9%$%C%A(B(%s)$B$,J,$j$^$;$s(B' + def_exception :NotImplementError, '`%s\'$B$NDj5A$,I,MW$G$9(B' + def_exception :CantRetuenNormalMode, 'Normal$B%b!<%I$KLa$l$^$;$s(B.' + def_exception :IllegalParameter, '$B%Q%i%a!<%?(B(%s)$B$,4V0c$C$F$$$^$9(B.' + def_exception :IrbAlreadyDead, 'Irb$B$O4{$K;`$s$G$$$^$9(B.' + def_exception :IrbSwitchToCurrentThread, 'Change to current thread.' + def_exception :NoSuchJob, '$B$=$N$h$&$J%8%g%V(B(%s)$B$O$"$j$^$;$s(B.' + def_exception :CanNotGoMultiIrbMode, 'multi-irb mode$B$K0\$l$^$;$s(B.' + def_exception :CanNotChangeBinding, '$B%P%$%s%G%#%s%0(B(%s)$B$KJQ99$G$-$^$;$s(B.' + def_exception :UndefinedPromptMode, '$B%W%m%s%W%H%b!<%I(B(%s)$B$ODj5A$5$l$F$$$^$;$s(B.' +end + + diff --git a/lib/irb/lc/ja/help-message b/lib/irb/lc/ja/help-message new file mode 100644 index 000000000..59f5c7a72 --- /dev/null +++ b/lib/irb/lc/ja/help-message @@ -0,0 +1,35 @@ +# +# irb/lc/ja/help-message.rb - +# $Release Version: 0.7.3$ +# $Revision$ +# $Date$ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# -- +# +# +# +Usage: irb.rb [options] [programfile] [arguments] + -f ~/.irbrc $B$rFI$_9~$^$J$$(B. + -m bc$B%b!<%I(B($BJ,?t(B, $B9TNs$N7W;;$,$G$-$k(B) + -d $DEBUG $B$r(Btrue$B$K$9$k(B(ruby -d $B$HF1$8(B) + -r load-module ruby -r $B$HF1$8(B. + --inspect $B7k2L=PNO$K(Binspect$B$rMQ$$$k(B(bc$B%b!<%I0J30$O%G%U%)%k%H(B). + --noinspect $B7k2L=PNO$K(Binspect$B$rMQ$$$J$$(B. + --readline readline$B%i%$%V%i%j$rMxMQ$9$k(B. + --noreadline readline$B%i%$%V%i%j$rMxMQ$7$J$$(B. + --prompt prompt-mode/--prompt-mode prompt-mode + $B%W%m%s%W%H%b!<%I$r@ZBX$($^$9(B. $B8=:_Dj5A$5$l$F$$$k%W(B + $B%m%s%W%H%b!<%I$O(B, defalut, simple, xmp, inf-ruby$B$,(B + $BMQ0U$5$l$F$$$^$9(B. + --inf-ruby-mode emacs$B$N(Binf-ruby-mode$BMQ$N%W%m%s%W%HI=<($r9T$J$&(B. $BFC(B + $B$K;XDj$,$J$$8B$j(B, readline$B%i%$%V%i%j$O;H$o$J$/$J$k(B. + --simple-prompt $BHs>o$K%7%s%W%k$J%W%m%s%W%H$rMQ$$$k%b!<%I$G$9(B. + --noprompt $B%W%m%s%W%HI=<($r9T$J$o$J$$(B. + --tracer $B%3%^%s%I<B9T;~$K%H%l!<%9$r9T$J$&(B. + --back-trace-limit n + $B%P%C%/%H%l!<%9I=<($r%P%C%/%H%l!<%9$NF,$+$i(B n, $B8e$m(B + $B$+$i(Bn$B$@$19T$J$&(B. $B%G%U%)%k%H$O(B16 + --irb_debug n irb$B$N%G%P%C%0%G%P%C%0%l%Y%k$r(Bn$B$K@_Dj$9$k(B($BMxMQ$7$J(B + $B$$J}$,L5Fq$G$7$g$&(B). + -v, --version irb$B$N%P!<%8%g%s$rI=<($9$k(B diff --git a/lib/irb/locale.rb b/lib/irb/locale.rb new file mode 100644 index 000000000..ef92ea137 --- /dev/null +++ b/lib/irb/locale.rb @@ -0,0 +1,187 @@ +# +# irb/locale.rb - internationalization module +# $Release Version: 0.7.3$ +# $Revision$ +# $Date$ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# -- +# +# +# + +require "kconv" + +module IRB + class Locale + @RCS_ID='-$Id$-' + + JPDefaultLocale = "ja" + LOCALE_DIR = "/lc/" + + LC2KCONV = { +# "ja" => Kconv::JIS, +# "ja_JP" => Kconv::JIS, + "ja_JP.ujis" => Kconv::EUC, + "ja_JP.euc" => Kconv::EUC, + "ja_JP.eucJP" => Kconv::EUC, + "ja_JP.sjis" => Kconv::SJIS, + "ja_JP.SJIS" => Kconv::SJIS, + } + + def initialize(locale = nil) + @lang = locale || ENV["IRB_LANG"] || ENV["LC_MESSAGES"] || ENV["LC_ALL"] || ENV["LANG"] + @lang = "C" unless @lang + end + + attr_reader :lang + + def String(mes) + mes = super(mes) + case @lang + when /^ja/ + mes = Kconv::kconv(mes, LC2KCONV[@lang]) + else + mes + end + mes + end + + def format(*opts) + String(super(*opts)) + end + + def gets(*rs) + String(super(*rs)) + end + + def readline(*rs) + String(super(*rs)) + end + + def print(*opts) + ary = opts.collect{|opt| String(opt)} + super *ary + end + + def printf(*opts) + s = format(*opts) + print s + end + + def puts(*opts) + ary = opts.collect{|opt| String(opts)} + super *ary + end + + autoload :Tempfile, "tempfile" + + def require(file, priv = nil) + rex = Regexp.new("lc/#{Regexp.quote(file)}\.(so|o|sl|rb)?") + return false if $".find{|f| f =~ rex} + + case file + when /\.rb$/ + begin + load(file, priv) + $".push file + return true + rescue LoadError + end + when /\.(so|o|sl)$/ + return super + end + + begin + load(f = file + ".rb") + $".push f #" + return true + rescue LoadError + return ruby_require(file) + end + end + + alias toplevel_load load + + def load(file, priv=nil) + dir = File.dirname(file) + dir = "" if dir == "." + base = File.basename(file) + + if /^ja(_JP)?$/ =~ @lang + back, @lang = @lang, "C" + end + begin + if dir[0] == ?/ #/ + lc_path = search_file(dir, base) + return real_load(lc_path, priv) if lc_path + end + + for path in $: + lc_path = search_file(path + "/" + dir, base) + return real_load(lc_path, priv) if lc_path + end + ensure + @lang = back if back + end + raise LoadError, "No such file to load -- #{file}" + end + + def real_load(path, priv) + tmp_base = path.tr("./:", "___") + lc_file = Tempfile.new(tmp_base) + File.foreach(path) do |line| + line = self.String(line) + lc_file.print(line) + end + lc_file.close + toplevel_load lc_file.path, priv + end + private :real_load + + def find(file , paths = $:) + dir = File.dirname(file) + dir = "" if dir == "." + base = File.basename(file) + if dir[0] == ?/ #/ + return lc_path = search_file(dir, base) + else + for path in $: + if lc_path = search_file(path + "/" + dir, base) + return lc_path + end + end + end + nil + end + + def search_file(path, file) + if File.exists?(p1 = path + lc_path(file, "C")) + if File.exists?(p2 = path + lc_path(file)) + return p2 + else + end + return p1 + else + end + nil + end + private :search_file + + def lc_path(file = "", lc = @lang) + case lc + when "C" + LOCALE_DIR + file + when /^ja/ + LOCALE_DIR + "ja/" + file + else + LOCALE_DIR + @lang + "/" + file + end + end + private :lc_path + end +end + + + + diff --git a/lib/irb/workspace.rb b/lib/irb/workspace.rb new file mode 100644 index 000000000..3550a758d --- /dev/null +++ b/lib/irb/workspace.rb @@ -0,0 +1,106 @@ +# +# irb/workspace-binding.rb - +# $Release Version: 0.7.3$ +# $Revision$ +# $Date$ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# -- +# +# +# +module IRB + class WorkSpace + # create new workspace. + # (JP: $B?7$?$J(Bworkspace$B$r:n$k(B. main$B$r(Bself$B$H$9$k(B. $B>JN,$7$?$i(B, + # TOPLEVEL_BINDING$B$N(Bmain$B$r$=$N$^$^;H$&(B. ) + def initialize(*main) + if IRB.conf[:SINGLE_IRB] + @binding = TOPLEVEL_BINDING + else + case IRB.conf[:CONTEXT_MODE] + when 0 # binding in proc on TOPLEVEL_BINDING + @binding = eval("proc{binding}.call", + TOPLEVEL_BINDING, + __FILE__, + __LINE__) + when 1 # binding in loaded file + require "tempfile" + f = Tempfile.open("irb-binding") + f.print <<EOF + $binding = binding +EOF + f.close + load f.path + @binding = $binding + + when 2 # binding in loaded file(thread use) + unless defined? BINDING_QUEUE + require "thread" + + IRB.const_set("BINDING_QUEUE", SizedQueue.new(1)) + Thread.abort_on_exception = true + Thread.start do + eval "require \"irb/ws-for-case-2\"", TOPLEVEL_BINDING, __FILE__, __LINE__ + end + Thread.pass + end + @binding = BINDING_QUEUE.pop + + when 3 # binging in function on TOPLEVEL_BINDING(default) + @binding = eval("def irb_binding; binding; end; irb_binding", + TOPLEVEL_BINDING, + __FILE__, + __LINE__ - 3) + end + end + if main.empty? + @main = eval "self", @binding + else + @main = main[0] + IRB.conf[:__MAIN__] = @main + case @main + when Module + @binding = eval("IRB.conf[:__MAIN__].module_eval('binding', __FILE__, __LINE__)", @binding, __FILE__, __LINE__) + else + begin + @binding = eval("IRB.conf[:__MAIN__].instance_eval('binding', __FILE__, __LINE__)", @binding, __FILE__, __LINE__) + rescue TypeError + IRB.fail CanNotChangeBinding, @main.inspect + end + end + end + eval("_=nil", @binding) + end + + attr_reader :binding + attr_reader :main + + def evaluate(statements, file = __FILE__, line = __LINE__) + eval statements, @binding, file, line + end + + # error message manupilator + def filter_backtrace(bt) + case IRB.conf[:CONTEXT_MODE] + when 0 + return nil if bt =~ /\(irb_local_binding\)/ + when 1 + if(bt =~ %r!/tmp/irb-binding! or + bt =~ %r!irb/.*\.rb! or + bt =~ /irb\.rb/) + return nil + end + when 2 + return nil if bt =~ /irb\/.*\.rb/ + when 3 + return nil if bt =~ /irb\/.*\.rb/ + bt.sub!(/:\s*in `irb_binding'/){""} + end + bt + end + + def IRB.delete_caller + end + end +end diff --git a/lib/irb/ws-for-case-2.rb b/lib/irb/ws-for-case-2.rb new file mode 100644 index 000000000..8cfa87ae3 --- /dev/null +++ b/lib/irb/ws-for-case-2.rb @@ -0,0 +1,15 @@ +# +# irb/ws-for-case-2.rb - +# $Release Version: 0.7.3$ +# $Revision$ +# $Date$ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# -- +# +# +# + +while true + IRB::BINDING_QUEUE.push b = binding +end |