mirror of
https://github.com/pry/pry.git
synced 2022-11-09 12:35:05 -05:00
changed get_prompt to select_prompt
This commit is contained in:
parent
878ca414d7
commit
70bc1222e2
8 changed files with 197 additions and 128 deletions
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
Makefile
|
||||
*.so
|
||||
*.o
|
||||
*.def
|
||||
doc/
|
||||
pkg/
|
||||
.yardoc/
|
|
@ -18,7 +18,7 @@ commands such as `show_method` and `jump_to`
|
|||
Example: Interacting with an object at runtime
|
||||
---------------------------------------
|
||||
|
||||
With the `Pry.start()` method we can pry (open an irb-like session) on
|
||||
With the `Object#pry` method we can pry (open an irb-like session) on
|
||||
an object. In the example below we open a Pry session for the `Test` class and execute a method and add
|
||||
an instance variable. The current thread is halted for the duration of the session.
|
||||
|
||||
|
@ -28,7 +28,7 @@ an instance variable. The current thread is halted for the duration of the sessi
|
|||
def self.hello() "hello world" end
|
||||
end
|
||||
|
||||
Pry.start(Test)
|
||||
Test.pry
|
||||
|
||||
# Pry session begins on stdin
|
||||
Beginning Pry session for Test
|
||||
|
@ -50,10 +50,10 @@ effect:
|
|||
|
||||
#### Alternative Syntax
|
||||
|
||||
You can also use the `obj.pry` or `pry(obj)` syntax to start a pry session on
|
||||
You can also use the `Pry.start(obj)` or `pry(obj)` syntax to start a pry session on
|
||||
`obj`. e.g
|
||||
|
||||
5.pry
|
||||
Pry.start 5
|
||||
Beginning Pry session for 5
|
||||
pry(5)>
|
||||
|
||||
|
@ -62,7 +62,7 @@ OR
|
|||
pry 6
|
||||
beginning Pry session for 6
|
||||
pry(6)>
|
||||
|
||||
|
||||
Example: Pry sessions can nest arbitrarily deep so we can pry on objects inside objects:
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -76,11 +76,11 @@ an instance variable inside that class:
|
|||
pry(main)* @x = 20
|
||||
pry(main)* end
|
||||
=> 20
|
||||
pry(main)> Pry.start Hello
|
||||
pry(main)> Hello.pry
|
||||
Beginning Pry session for Hello
|
||||
pry(Hello):1> instance_variables
|
||||
=> [:@x]
|
||||
pry(Hello):1> Pry.start @x
|
||||
pry(Hello):1> @x.pry
|
||||
Beginning Pry session for 20
|
||||
pry(20:2)> self + 10
|
||||
=> 30
|
||||
|
@ -143,8 +143,9 @@ end.
|
|||
* Pry can be invoked at any time and on any object in the running program.
|
||||
* Pry sessions can nest arbitrarily deeply -- to go back one level of nesting type 'exit' or 'quit' or 'back'
|
||||
* Use `_` to recover last result.
|
||||
* Use `_pry_` to reference the Pry instance managing the current session.
|
||||
* Pry has multi-line support built in.
|
||||
* Pry has unique commands not found in any other REPL: `show_method`, `show_doc`
|
||||
* Pry has special commands not found in many other Ruby REPLs: `show_method`, `show_doc`
|
||||
`jump_to`, `ls`, `cd`, `cat`
|
||||
* Pry gives good control over nested sessions (important when exploring complicated runtime state)
|
||||
* Pry is not based on the IRB codebase.
|
||||
|
@ -173,7 +174,22 @@ Commands
|
|||
receives as a parameter. In the case of no parameter it operates on
|
||||
top-level (main). It can receive any object or a `Binding`
|
||||
object as parameter. `Pry.start()` is implemented as `Pry.new.repl()`
|
||||
* `obj.pry` and `pry(obj)` may also be used as alternative syntax to `Pry.start(obj)`
|
||||
* `obj.pry` and `pry(obj)` may also be used as alternative syntax to
|
||||
`Pry.start(obj)`.
|
||||
|
||||
However there are some differences. `obj.pry` opens
|
||||
a Pry session on the receiver whereas `Pry.start` (with no parameter)
|
||||
will start a Pry session on top-level. The other form of the `pry`
|
||||
method: `pry(obj)` will also start a Pry session on its parameter.
|
||||
|
||||
The `pry` method invoked by itself, with no explict receiver and no
|
||||
parameter will start a Pry session on the implied receiver. It is
|
||||
perhaps more useful to invoke it in this form `pry(binding)` or
|
||||
`binding.pry` so as to get access to locals in the current context.
|
||||
|
||||
Another difference is that `Pry.start()` accepts a second parameter
|
||||
that is a hash of configuration options (discussed further, below).
|
||||
|
||||
* If, for some reason you do not want to 'loop' then use `Pry.new.rep()`; it
|
||||
only performs the Read-Eval-Print section of the REPL - it ends the
|
||||
session after just one line of input. It takes the same parameters as
|
||||
|
@ -202,8 +218,8 @@ If you want to access a method of the same name, prefix the invocation by whites
|
|||
are nested sessions).
|
||||
* `ls` returns a list of local variables and instance variables in the
|
||||
current scope
|
||||
* `cat <var>` calls `inspect` on `<var>`
|
||||
* `cd <var>` starts a `Pry` session on the variable <var>. E.g `cd @x`
|
||||
* `cat <var>` Calls `inspect` on `<var>`
|
||||
* `cd <var>` Starts a `Pry` session on the variable <var>. E.g `cd @x`
|
||||
* `show_method <methname>` Displays the sourcecode for the method
|
||||
<methname>. E.g `show_method hello`
|
||||
* `show_imethod <methname>` Displays the sourcecode for the
|
||||
|
@ -213,8 +229,10 @@ If you want to access a method of the same name, prefix the invocation by whites
|
|||
method `<methname>`
|
||||
* `exit_program` or `quit_program` will end the currently running
|
||||
program.
|
||||
* `nesting` shows Pry nesting information.
|
||||
* `jump_to <nest_level>` unwinds the Pry stack (nesting level) until the appropriate nesting level is reached
|
||||
* `nesting` Shows Pry nesting information.
|
||||
* `!pry` Starts a Pry session on the implied receiver; this can be
|
||||
used in the middle of an expression in multi-line input.
|
||||
* `jump_to <nest_level>` Unwinds the Pry stack (nesting level) until the appropriate nesting level is reached
|
||||
-- as per the output of `nesting`
|
||||
* `exit_all` breaks out of all Pry nesting levels and returns to the
|
||||
calling process.
|
||||
|
@ -222,6 +240,33 @@ If you want to access a method of the same name, prefix the invocation by whites
|
|||
current one with `obj` as the receiver of the new session. Very useful
|
||||
when exploring large or complicated runtime state.
|
||||
|
||||
Customizing Pry
|
||||
---------------
|
||||
|
||||
Pry supports customization of the input, the output, the commands,
|
||||
the hooks, the prompt, and 'print' (the "P" in REPL).
|
||||
|
||||
Global customization, which applies to all Pry sessions, is done
|
||||
through invoking class accessors on the `Pry` class, the accessors
|
||||
are:
|
||||
|
||||
* `Pry.input=`
|
||||
* `Pry.output=`
|
||||
* `Pry.commands=`
|
||||
* `Pry.hooks=`
|
||||
* `Pry.prompt=`
|
||||
* `Pry.print=`
|
||||
|
||||
Local customization (applied to a single Pry session) is done by
|
||||
passing config hash options to `Pry.start()` or to `Pry.new()`; also the
|
||||
same accessors as described above for the `Pry` class also exist for a
|
||||
Pry instance.
|
||||
|
||||
### Input:
|
||||
|
||||
|
||||
|
||||
|
||||
Contact
|
||||
-------
|
||||
|
||||
|
|
|
@ -1,22 +1,60 @@
|
|||
require 'readline'
|
||||
|
||||
class Pry
|
||||
|
||||
# default input class - uses Readline.
|
||||
class Input
|
||||
trap('INT') { exit }
|
||||
|
||||
def read(prompt)
|
||||
def readline(prompt)
|
||||
Readline.readline(prompt, true)
|
||||
end
|
||||
end
|
||||
|
||||
# read from any IO-alike
|
||||
class IOInput
|
||||
def initialize(io)
|
||||
@io = io
|
||||
end
|
||||
|
||||
def readline
|
||||
@io.readline
|
||||
end
|
||||
|
||||
def close
|
||||
@io.close
|
||||
end
|
||||
end
|
||||
|
||||
# file input class
|
||||
class FileInput
|
||||
def initialize(file, line = 1)
|
||||
@f = File.open(file)
|
||||
(line - 1).times { @f.readline }
|
||||
end
|
||||
|
||||
def read(prompt)
|
||||
def readline(prompt)
|
||||
@f.readline
|
||||
end
|
||||
|
||||
def close
|
||||
@f.close
|
||||
end
|
||||
end
|
||||
|
||||
# preset input class
|
||||
class PresetInput
|
||||
def initialize(*actions)
|
||||
@orig_actions = actions.dup
|
||||
@actions = actions
|
||||
end
|
||||
|
||||
def readline(*)
|
||||
@actions.shift
|
||||
end
|
||||
|
||||
def rewind
|
||||
@actions = @orig_actions.dup
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
class Pry
|
||||
|
||||
# default output class - just writes to STDOUT
|
||||
class Output
|
||||
attr_reader :out
|
||||
|
||||
|
@ -11,8 +13,8 @@ class Pry
|
|||
end
|
||||
end
|
||||
|
||||
# null output class - doesn't write anywwhere.
|
||||
class NullOutput
|
||||
def puts(*) end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -81,8 +81,8 @@ class Pry
|
|||
|
||||
# Set all the configurable options back to their default values
|
||||
def self.reset_defaults
|
||||
@input = Input.new
|
||||
@output = Output.new
|
||||
@input = Readline
|
||||
@output = $stdout
|
||||
@commands = Commands.new
|
||||
@prompt = DEFAULT_PROMPT
|
||||
@print = DEFAULT_PRINT
|
||||
|
|
|
@ -138,9 +138,21 @@ class Pry
|
|||
target = binding_for(target)
|
||||
eval_string = ""
|
||||
loop do
|
||||
val = input.read(get_prompt(eval_string.empty?, target.eval('self')))
|
||||
|
||||
val = if input == Readline
|
||||
input.readline(select_prompt(eval_string.empty?, target.eval('self')), true)
|
||||
else
|
||||
if input.method(:readline).arity == 1
|
||||
input.readline(select_prompt(eval_string.empty?, target.eval('self')))
|
||||
else
|
||||
input.readline
|
||||
end
|
||||
end
|
||||
|
||||
val.chomp!
|
||||
|
||||
process_commands(val, eval_string, target)
|
||||
eval_string << "#{val.chomp}\n"
|
||||
eval_string << "#{val}\n"
|
||||
|
||||
break eval_string if valid_expression?(eval_string)
|
||||
end
|
||||
|
@ -154,9 +166,9 @@ class Pry
|
|||
# @param [String] val The current line of input.
|
||||
# @param [String] eval_string The cumulative lines of input for
|
||||
# multi-line input.
|
||||
# @param [Object] target The receiver of the commands.
|
||||
# @param [Binding] target The receiver of the commands.
|
||||
def process_commands(val, eval_string, target)
|
||||
def eval_string.clear() replace("") end
|
||||
def val.clear() replace("") end
|
||||
|
||||
pattern, action = commands.commands.find { |k, v| Array(k).any? { |a| a === val } }
|
||||
|
||||
|
@ -182,7 +194,7 @@ class Pry
|
|||
# (and not multi-line input).
|
||||
# @param [Object] target_self The receiver of the Pry session.
|
||||
# @return [String] The prompt.
|
||||
def get_prompt(first_line, target_self)
|
||||
def select_prompt(first_line, target_self)
|
||||
|
||||
if first_line
|
||||
Array(prompt).first.call(target_self, nesting.level)
|
||||
|
|
173
test/test.rb
173
test/test.rb
|
@ -68,8 +68,7 @@ describe Pry do
|
|||
|
||||
o = Object.new
|
||||
|
||||
pry_tester = Pry.new(:input => input, :output => Pry::NullOutput.new)
|
||||
pry_tester.repl(o)
|
||||
pry_tester = Pry.start(o, :input => input, :output => Pry::NullOutput.new)
|
||||
|
||||
o.instance_variable_get(:@x).should == 10
|
||||
end
|
||||
|
@ -79,8 +78,7 @@ describe Pry do
|
|||
str_output = StringIO.new
|
||||
o = Object.new
|
||||
|
||||
pry_tester = Pry.new(:input => input, :output => Pry::Output.new(str_output))
|
||||
pry_tester.repl(o)
|
||||
pry_tester = Pry.start(o, :input => input, :output => Pry::Output.new(str_output))
|
||||
str_output.string.should =~ /Beginning.*#{o}/
|
||||
str_output.string.should =~ /Ending.*#{o}/
|
||||
end
|
||||
|
@ -95,8 +93,7 @@ describe Pry do
|
|||
|
||||
o = Object.new
|
||||
|
||||
pry_tester = Pry.new
|
||||
pry_tester.repl(o)
|
||||
pry_tester = o.pry
|
||||
str_output.string.should =~ /nest:3/
|
||||
|
||||
Pry.input = Pry::Input.new
|
||||
|
@ -134,7 +131,55 @@ describe Pry do
|
|||
end
|
||||
end
|
||||
|
||||
describe "Object#pry" do
|
||||
|
||||
after do
|
||||
Pry.reset_defaults
|
||||
end
|
||||
|
||||
it "should start a pry session on the receiver (first form)" do
|
||||
Pry.input = InputTester.new("self", "exit")
|
||||
|
||||
str_output = StringIO.new
|
||||
Pry.output = Pry::Output.new(str_output)
|
||||
|
||||
20.pry
|
||||
|
||||
str_output.string.should =~ /20/
|
||||
end
|
||||
|
||||
it "should start a pry session on the receiver (second form)" do
|
||||
Pry.input = InputTester.new("self", "exit")
|
||||
|
||||
str_output = StringIO.new
|
||||
Pry.output = Pry::Output.new(str_output)
|
||||
|
||||
pry 20
|
||||
|
||||
str_output.string.should =~ /20/
|
||||
end
|
||||
|
||||
it "should error if more than one argument is passed to Object#pry" do
|
||||
lambda { pry(20, :input => Pry::Input.new) }.should.raise ArgumentError
|
||||
end
|
||||
end
|
||||
|
||||
describe "Pry#binding_for" do
|
||||
it 'should return TOPLEVEL_BINDING if parameter self is main' do
|
||||
_main_ = lambda { TOPLEVEL_BINDING.eval('self') }
|
||||
Pry.new.binding_for(_main_.call).is_a?(Binding).should == true
|
||||
Pry.new.binding_for(_main_.call).should == TOPLEVEL_BINDING
|
||||
Pry.new.binding_for(_main_.call).should == Pry.new.binding_for(_main_.call)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
describe "test Pry defaults" do
|
||||
|
||||
after do
|
||||
Pry.reset_defaults
|
||||
end
|
||||
|
||||
it 'should set the input default, and the default should be overridable' do
|
||||
Pry.input = InputTester.new("5")
|
||||
|
||||
|
@ -145,8 +190,6 @@ describe Pry do
|
|||
|
||||
Pry.new(:input => InputTester.new("6")).rep
|
||||
str_output.string.should =~ /6/
|
||||
|
||||
Pry.reset_defaults
|
||||
end
|
||||
|
||||
it 'should set the output default, and the default should be overridable' do
|
||||
|
@ -165,13 +208,9 @@ describe Pry do
|
|||
Pry.new(:output => Pry::Output.new(str_output2)).rep
|
||||
str_output2.string.should.not =~ /5\n.*6/
|
||||
str_output2.string.should =~ /7/
|
||||
|
||||
Pry.reset_defaults
|
||||
end
|
||||
|
||||
it 'should set the commands default, and the default should be overridable' do
|
||||
Pry.reset_defaults
|
||||
|
||||
commands = {
|
||||
"hello" => proc { |opts| opts[:output].puts "hello world"; opts[:val].clear }
|
||||
}
|
||||
|
@ -193,8 +232,6 @@ describe Pry do
|
|||
|
||||
Pry.new(:input => InputTester.new("goodbye"), :output => Pry::Output.new(str_output), :commands => commands).rep
|
||||
str_output.string.should =~ /goodbye world/
|
||||
|
||||
Pry.reset_defaults
|
||||
end
|
||||
|
||||
|
||||
|
@ -216,8 +253,6 @@ describe Pry do
|
|||
str_output = StringIO.new
|
||||
Pry.new(:input => InputTester.new("\"test\""), :output => str_output).rep
|
||||
str_output.string.should == "test\n"
|
||||
|
||||
Pry.reset_defaults
|
||||
end
|
||||
|
||||
describe "prompts" do
|
||||
|
@ -226,18 +261,18 @@ describe Pry do
|
|||
Pry.prompt = new_prompt
|
||||
|
||||
Pry.new.prompt.should == Pry.prompt
|
||||
Pry.new.get_prompt(true, 0).should == "test prompt> "
|
||||
Pry.new.get_prompt(false, 0).should == "test prompt> "
|
||||
Pry.new.select_prompt(true, 0).should == "test prompt> "
|
||||
Pry.new.select_prompt(false, 0).should == "test prompt> "
|
||||
|
||||
new_prompt = proc { "A" }
|
||||
pry_tester = Pry.new(:prompt => new_prompt)
|
||||
pry_tester.prompt.should == new_prompt
|
||||
pry_tester.get_prompt(true, 0).should == "A"
|
||||
pry_tester.get_prompt(false, 0).should == "A"
|
||||
pry_tester.select_prompt(true, 0).should == "A"
|
||||
pry_tester.select_prompt(false, 0).should == "A"
|
||||
|
||||
Pry.new.prompt.should == Pry.prompt
|
||||
Pry.new.get_prompt(true, 0).should == "test prompt> "
|
||||
Pry.new.get_prompt(false, 0).should == "test prompt> "
|
||||
Pry.new.select_prompt(true, 0).should == "test prompt> "
|
||||
Pry.new.select_prompt(false, 0).should == "test prompt> "
|
||||
end
|
||||
|
||||
it 'should set the prompt default, and the default should be overridable (multi prompt)' do
|
||||
|
@ -245,26 +280,26 @@ describe Pry do
|
|||
Pry.prompt = new_prompt
|
||||
|
||||
Pry.new.prompt.should == Pry.prompt
|
||||
Pry.new.get_prompt(true, 0).should == "test prompt> "
|
||||
Pry.new.get_prompt(false, 0).should == "test prompt* "
|
||||
Pry.new.select_prompt(true, 0).should == "test prompt> "
|
||||
Pry.new.select_prompt(false, 0).should == "test prompt* "
|
||||
|
||||
new_prompt = [proc { "A" }, proc { "B" }]
|
||||
pry_tester = Pry.new(:prompt => new_prompt)
|
||||
pry_tester.prompt.should == new_prompt
|
||||
pry_tester.get_prompt(true, 0).should == "A"
|
||||
pry_tester.get_prompt(false, 0).should == "B"
|
||||
pry_tester.select_prompt(true, 0).should == "A"
|
||||
pry_tester.select_prompt(false, 0).should == "B"
|
||||
|
||||
Pry.new.prompt.should == Pry.prompt
|
||||
Pry.new.get_prompt(true, 0).should == "test prompt> "
|
||||
Pry.new.get_prompt(false, 0).should == "test prompt* "
|
||||
Pry.new.select_prompt(true, 0).should == "test prompt> "
|
||||
Pry.new.select_prompt(false, 0).should == "test prompt* "
|
||||
end
|
||||
end
|
||||
|
||||
it 'should set the hooks default, and the default should be overridable' do
|
||||
Pry.input = InputTester.new("exit")
|
||||
Pry.hooks = {
|
||||
:before_session => proc { |out| out.puts "HELLO" },
|
||||
:after_session => proc { |out| out.puts "BYE" }
|
||||
:before_session => proc { |out,_| out.puts "HELLO" },
|
||||
:after_session => proc { |out,_| out.puts "BYE" }
|
||||
}
|
||||
|
||||
str_output = StringIO.new
|
||||
|
@ -277,8 +312,8 @@ describe Pry do
|
|||
str_output = StringIO.new
|
||||
Pry.new(:output => Pry::Output.new(str_output),
|
||||
:hooks => {
|
||||
:before_session => proc { |out| out.puts "MORNING" },
|
||||
:after_session => proc { |out| out.puts "EVENING" }
|
||||
:before_session => proc { |out,_| out.puts "MORNING" },
|
||||
:after_session => proc { |out,_| out.puts "EVENING" }
|
||||
}
|
||||
).repl
|
||||
|
||||
|
@ -290,7 +325,7 @@ describe Pry do
|
|||
str_output = StringIO.new
|
||||
Pry.new(:output => Pry::Output.new(str_output),
|
||||
:hooks => {
|
||||
:before_session => proc { |out| out.puts "OPEN" }
|
||||
:before_session => proc { |out,_| out.puts "OPEN" }
|
||||
}
|
||||
).repl
|
||||
|
||||
|
@ -300,7 +335,7 @@ describe Pry do
|
|||
str_output = StringIO.new
|
||||
Pry.new(:output => Pry::Output.new(str_output),
|
||||
:hooks => {
|
||||
:after_session => proc { |out| out.puts "CLOSE" }
|
||||
:after_session => proc { |out,_| out.puts "CLOSE" }
|
||||
}
|
||||
).repl
|
||||
|
||||
|
@ -308,77 +343,7 @@ describe Pry do
|
|||
|
||||
Pry.reset_defaults
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
# commands = {
|
||||
# "!" => "refresh",
|
||||
# "help" => "show_help",
|
||||
# "nesting" => "show_nesting",
|
||||
# "status" => "show_status",
|
||||
# "cat dummy" => "cat",
|
||||
# "cd 3" => "cd",
|
||||
# "ls" => "ls",
|
||||
# "jump_to 0" => "jump_to",
|
||||
# "show_method test_method" => "show_method",
|
||||
# "show_imethod test_method" => "show_method",
|
||||
# "show_doc test_method" => "show_doc",
|
||||
# "show_idoc test_method" => "show_doc"
|
||||
# }
|
||||
|
||||
# commands.each do |command, meth|
|
||||
|
||||
# if RUBY_VERSION =~ /1.8/ && NOT_FOR_RUBY_18.any? { |v| v =~ command }
|
||||
# next
|
||||
# end
|
||||
|
||||
# eval %{
|
||||
# it "should invoke output##{meth} when #{command} command entered" do
|
||||
# input_strings = ["#{command}", "exit"]
|
||||
# input = InputTester.new(*input_strings)
|
||||
# output = OutputTester.new
|
||||
# o = Class.new
|
||||
|
||||
# pry_tester = Pry.new(:input => input, :output => output)
|
||||
# pry_tester.repl(o)
|
||||
|
||||
# output.#{meth}_invoked.should == true
|
||||
# output.session_end_invoked.should == true
|
||||
# end
|
||||
# }
|
||||
# end
|
||||
|
||||
# commands.each do |command, meth|
|
||||
|
||||
# if RUBY_VERSION =~ /1.8/ && NOT_FOR_RUBY_18.include?(command)
|
||||
# next
|
||||
# end
|
||||
|
||||
# eval %{
|
||||
# it "should raise when trying to invoke #{command} command with preceding whitespace" do
|
||||
# input_strings = [" #{command}", "exit"]
|
||||
# input = InputTester.new(*input_strings)
|
||||
# output = OutputTester.new
|
||||
# o = Class.new
|
||||
|
||||
# pry_tester = Pry.new(:input => input, :output => output)
|
||||
# pry_tester.repl(o)
|
||||
|
||||
# if "#{command}" != "!"
|
||||
# output.output_buffer.is_a?(NameError).should == true
|
||||
# else
|
||||
|
||||
# # because entering " !" in pry doesnt cause error, it
|
||||
# # just creates a wait prompt which the subsquent
|
||||
# # "exit" escapes from
|
||||
# output.output_buffer.should == ""
|
||||
# end
|
||||
# end
|
||||
# }
|
||||
# end
|
||||
# end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,7 +9,7 @@ class InputTester
|
|||
@actions = actions
|
||||
end
|
||||
|
||||
def read(*)
|
||||
def readline(*)
|
||||
@actions.shift
|
||||
end
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue