davidrichards-sirb 0.6.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. data/README.rdoc +227 -0
  2. data/VERSION.yml +4 -0
  3. data/bin/sirb +33 -0
  4. data/lib/overrides/array.rb +6 -0
  5. data/lib/overrides/file.rb +17 -0
  6. data/lib/overrides/module.rb +70 -0
  7. data/lib/overrides/symbol.rb +39 -0
  8. data/lib/sirb/enumerable_statistics.rb +350 -0
  9. data/lib/sirb/functional.rb +114 -0
  10. data/lib/sirb/general_statistics.rb +72 -0
  11. data/lib/sirb/inter_enumerable_statistics.rb +139 -0
  12. data/lib/sirb/lib_loader.rb +45 -0
  13. data/lib/sirb/runner.rb +274 -0
  14. data/lib/sirb/sproc/proc.rb +5 -0
  15. data/lib/sirb/sproc/proc_source.rb +130 -0
  16. data/lib/sirb/sproc/sproc.rb +79 -0
  17. data/lib/sirb/sproc/usage_notes.txt +25 -0
  18. data/lib/sirb/sproc.rb +29 -0
  19. data/lib/sirb/thread_support.rb +20 -0
  20. data/lib/sirb/unbound_method.rb +5 -0
  21. data/lib/sirb.rb +52 -0
  22. data/lib/stored_procedures.rb +10 -0
  23. data/spec/lib/overrides/array_spec.rb +7 -0
  24. data/spec/lib/overrides/file_spec.rb +13 -0
  25. data/spec/lib/overrides/module_spec.rb +86 -0
  26. data/spec/lib/overrides/symbol_spec.rb +39 -0
  27. data/spec/lib/sirb/enumerable_statistics_spec.rb +85 -0
  28. data/spec/lib/sirb/functional_spec.rb +75 -0
  29. data/spec/lib/sirb/general_statistics_spec.rb +40 -0
  30. data/spec/lib/sirb/inter_enumerable_statistics_spec.rb +55 -0
  31. data/spec/lib/sirb/lib_loader_spec.rb +39 -0
  32. data/spec/lib/sirb/runner_spec.rb +9 -0
  33. data/spec/lib/sirb/sproc/proc_spec.rb +9 -0
  34. data/spec/lib/sirb/sproc/sproc_spec.rb +25 -0
  35. data/spec/lib/sirb/unbound_method_spec.rb +12 -0
  36. data/spec/lib/sirb_spec.rb +9 -0
  37. data/spec/spec_helper.rb +15 -0
  38. metadata +97 -0
@@ -0,0 +1,45 @@
1
+ class LibLoader
2
+ class << self
3
+ def libs
4
+ @libs ||= {}
5
+ end
6
+
7
+ def add_lib(name, &block)
8
+ name = name.to_s
9
+ block ||= lambda{require name}
10
+ self.libs[name] = self.safe_require(&block)
11
+ end
12
+
13
+ def all_libs
14
+ self.libs.keys.sort
15
+ end
16
+
17
+ def libs_loaded
18
+ self.libs.map {|k, v| k if v }.compact
19
+ end
20
+
21
+ def failed_libs
22
+ self.libs.map {|k, v| k unless v }.compact
23
+ end
24
+
25
+ def safe_require(&block)
26
+ begin
27
+ block.call
28
+ # If the lib is already loaded, it may return false, but it's available.
29
+ # If there's a problem with this, you should require the lib in a block
30
+ # and raise an exception if it fails.
31
+ true
32
+ # If the laod returns false, then
33
+ rescue Exception => e # Very important
34
+ false
35
+ end
36
+ end
37
+
38
+ def to_s
39
+ return nil if self.failed_libs.empty?
40
+ "Libs loaded:\n\t" + (self.libs_loaded.empty? ? "None" : self.libs_loaded.join(", ")) +
41
+ "\nLibs NOT loaded:\n\t" + (self.failed_libs.empty? ? "None" : self.failed_libs.join(", "))
42
+ end
43
+ end
44
+
45
+ end
@@ -0,0 +1,274 @@
1
+ # So, this is interesting. It's a class to store operations from blocks,
2
+ # and run them.
3
+
4
+ # Persistent Store from Standard Library
5
+ require 'pstore'
6
+
7
+ module Sirb #:nodoc:
8
+
9
+ class Runner
10
+ class << self
11
+
12
+ # Storing everything in local .pstore for now. Uses the home directory,when possible.
13
+ def pstore
14
+ File.mkdir_p(dirname)
15
+ @@pstore ||= PStore.new(filename)
16
+ end
17
+ protected :pstore
18
+
19
+ def dirname
20
+ @@dirname ||= File.expand_path(File.join(ENV['HOME'], '.sirb'))
21
+ end
22
+ protected :dirname
23
+
24
+ def filename
25
+ @@filename ||= File.join(dirname, "proc.pstore")
26
+ end
27
+ protected :filename
28
+
29
+ # Needs a lambda, instead of a block, because we're serializing this and
30
+ # the code I use to serialize this needs to be able to find the string
31
+ # that created this code.
32
+ def add_command(name, l, description=nil)
33
+ coerce name
34
+ pstore.transaction { pstore[@name] = new(name.to_s, l, description) }
35
+ end
36
+
37
+ def remove_command(name)
38
+ coerce name
39
+ pstore.transaction { pstore.delete(@name) }
40
+ end
41
+
42
+ # Very harsh, but necessary if you have an unknown issue with a stored block.
43
+ def reset_commands
44
+ puts "Are you sure you want to remove all commands?(yN)\nThis will delete the contents of #{filename}"
45
+ result = gets.strip
46
+ return false unless result == 'y'
47
+ `rm -rf #{filename}`
48
+ puts "Successfully reset all commands."
49
+ end
50
+
51
+ def commands
52
+ pstore.transaction { pstore.roots }
53
+ end
54
+
55
+ def commands_as_commands
56
+ commands.map {|cmd| find(cmd)}
57
+ end
58
+ protected :commands_as_commands
59
+
60
+ def find(name)
61
+ return nil unless name
62
+ coerce name
63
+ begin
64
+ pstore.transaction { pstore[@name] }
65
+ rescue Exception => e
66
+ # Don't know a good way to look in the pstore for something that doesn't
67
+ # exist
68
+ nil
69
+ end
70
+ end
71
+
72
+ def methodize(name)
73
+ eval stringify_proc(name)
74
+ end
75
+
76
+ def stringify_proc(name)
77
+ cmd = find(name)
78
+ cmd_name = cmd.name
79
+ matched = cmd.block_source.match(/^(\|.+\|)(.+)$/)
80
+ cmd_params = matched ? matched[1] : ''
81
+ cmd_body = matched ? matched[2] : nil
82
+ cmd_body ||= cmd.block_source
83
+ cmd_body.lstrip!
84
+ "def #{cmd_name}(#{cmd_params})\n#{cmd_body}"
85
+ end
86
+
87
+ def run(name, *data)
88
+ coerce name
89
+ raise ArgumentError, "Unknown command: #{name}" unless self.find(@name)
90
+ self.find(@name).run(*data)
91
+ end
92
+
93
+ def coerce(name)
94
+ @name = name.to_sym
95
+ end
96
+ protected :coerce
97
+
98
+ def sirb_help(command=nil)
99
+ return puts(command_help(command)) if command
100
+ puts(sirb_description, all_commands_description, '')
101
+ end
102
+
103
+ def sirb_description
104
+
105
+ result = left_justify %{
106
+ This is Irb, with some extra libraries and commands loaded.
107
+ You have loaded the following libraries:
108
+ }
109
+ result += tab_indent( LibLoader.libs_loaded.join("\n") )
110
+ result += "\n\n"
111
+
112
+ if not LibLoader.failed_libs.empty?
113
+ result += "The following libraries are not available on your system at this time:\n"
114
+ result += tab_indent( LibLoader.failed_libs.join("\n") )
115
+ result += "\n\n"
116
+ end
117
+
118
+ result
119
+ end
120
+
121
+ def all_commands_description
122
+ result = ''
123
+
124
+ if commands.empty?
125
+ result += "You have not stored any custom commands at this time.\n\n"
126
+ else
127
+ result += "You have setup the following commands:\n\n"
128
+ result += commands_as_commands.map{ |cmd| cmd.command_help }.join("\n")
129
+ result += "\n\n"
130
+ end
131
+
132
+ result += "You can store a command like this:\n"
133
+ result += tab_indent(%{
134
+ set :command_name, lambda{|list params| command }, "Optional description"
135
+ })
136
+
137
+ result
138
+
139
+ end
140
+ protected :all_commands_description
141
+
142
+ def command_help(command)
143
+ cmd = find(command)
144
+ cmd ? cmd.command_help : "Could not find the command: #{command}"
145
+ end
146
+ protected :command_help
147
+
148
+ # Probably need to setup some decorators here instead...
149
+ def tab_indent(str)
150
+ return "" unless str
151
+ str.strip.split("\n").map {|line| "\t#{line.strip}" }.join("\n")
152
+ end
153
+
154
+ def left_justify(str)
155
+ return "" unless str
156
+ str.split("\n").map {|line| line.lstrip }.join("\n")
157
+ end
158
+
159
+ end
160
+
161
+ attr_reader :name, :description
162
+ # Needs a lambda, instead of a block, because we're serializing this and
163
+ # the code I use to serialize this needs to be able to find the string
164
+ # that created this code.
165
+ def initialize(name, l, description=nil)
166
+ @name, @block, @description = name, l, description
167
+ end
168
+
169
+ # Kind of loose: allows me to use reduce, map, or just call a stored
170
+ # command. This may just seem to work, but we'll see.
171
+ def run(*data)
172
+ case @block.arity
173
+ when 2
174
+ # Same as reduce
175
+ data.inject &@block
176
+ when 1
177
+ # Same as map
178
+ data.map &@block
179
+ when -1
180
+ # Same as call
181
+ @block.call
182
+ else
183
+ # Probably not going to work.
184
+ data.inject &@block
185
+ end
186
+ end
187
+
188
+ def command_help
189
+ result = (self.description and not self.description.empty?) ? formatted_description : empty_description
190
+ result + source_description
191
+ end
192
+
193
+ def arity_desc
194
+ case @block.arity
195
+ when -1
196
+ "takes 0 arguments"
197
+ when 1
198
+ "takes 1 argument, returns an array"
199
+ when 2
200
+ "takes 2 arguments, returns a single value--reduce function"
201
+ else
202
+ "takes #{@block.arity} arguments"
203
+ end
204
+ end
205
+ protected :arity_desc
206
+
207
+ def block_source
208
+ @block.source
209
+ end
210
+
211
+ def name_line
212
+ "* #{self.name} (#{arity_desc})\n"
213
+ end
214
+ protected :name_line
215
+
216
+ def source_description
217
+ "\n\tSource: #{block_source}"
218
+ end
219
+
220
+ def empty_description
221
+ "#{name_line}\tThere is no other information available for the #{self.name.to_s} command."
222
+ end
223
+ protected :empty_description
224
+
225
+ def formatted_description
226
+ name_line +
227
+ Runner.tab_indent(self.description)
228
+ end
229
+ protected :formatted_description
230
+
231
+ end
232
+
233
+ # These should be available in the console generally
234
+ module CommandLineMethods
235
+
236
+ def store_command(name, l, description=nil)
237
+ cmd = Runner.add_command(name, l, description)
238
+ cmd.name.to_s + " added"
239
+ end
240
+ alias set store_command
241
+
242
+
243
+ # May want to move this to delegate (standard library)
244
+ # http://www.ruby-doc.org/stdlib/libdoc/delegate/rdoc/index.html
245
+ def method_missing(sym, *args, &block)
246
+ # base, extension = breakdown_method(sym)
247
+ # if Runner.find(base) and extension == 'methodize'
248
+ # Runner.methodize(base)
249
+ # elsif Runner.find(base) and extension == 'to_s'
250
+ # require 'rubygems'
251
+ # require 'ruby-debug'
252
+ # debugger
253
+ # Runner.stringify_proc(base)
254
+ if Runner.find(sym)
255
+ Runner.run(sym, *args)
256
+ # elsif Runner.respond_to?(sym)
257
+ elsif Runner.respond_to?(sym)
258
+ Runner.send(sym, *args, &block)
259
+ else
260
+ super
261
+ end
262
+ end
263
+
264
+ # Doesn't work.
265
+ def breakdown_method(sym)
266
+ s = sym.to_s
267
+ r = /^(.+)\.(.+)$/
268
+ md = s.match r
269
+ md ? [md[1].to_sym, md[2]] : [nil,nil]
270
+ end
271
+ protected :breakdown_method
272
+ end
273
+
274
+ end
@@ -0,0 +1,5 @@
1
+ class Proc
2
+ def to_sproc
3
+ Sproc.new(&self)
4
+ end
5
+ end
@@ -0,0 +1,130 @@
1
+ require 'stringio'
2
+ require 'irb/ruby-lex'
3
+
4
+ # Tell the ruby interpreter to load code lines of required files
5
+ # into this filename -> lines Hash. This behaviour seems to be
6
+ # very undocumented and therefore shouldn't really be relied on.
7
+ SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
8
+
9
+ module ProcSource
10
+ def get_lines(filename, start_line = 0)
11
+ case filename
12
+ # special "(irb)" descriptor?
13
+ when "(irb)"
14
+ IRB.conf[:MAIN_CONTEXT].io.line(start_line .. -1)
15
+ # special "(eval...)" descriptor?
16
+ when /^\(eval.+\)$/
17
+ EVAL_LINES__[filename][start_line .. -1]
18
+ # regular file
19
+ else
20
+ # Ruby already parsed this file? (see disclaimer above)
21
+ if lines = SCRIPT_LINES__[filename]
22
+ lines[(start_line - 1) .. -1]
23
+ # If the file exists we're going to try reading it in
24
+ elsif File.exist?(filename)
25
+ begin
26
+ File.readlines(filename)[(start_line - 1) .. -1]
27
+ rescue
28
+ nil
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ def handle(proc)
35
+ filename, line = proc.source_descriptor
36
+ lines = get_lines(filename, line) || []
37
+
38
+ lexer = RubyLex.new
39
+ lexer.set_input(StringIO.new(lines.join))
40
+
41
+ state = :before_constructor
42
+ nesting_level = 1
43
+ start_token, end_token = nil, nil
44
+ found = false
45
+ while token = lexer.token
46
+ # we've not yet found any proc-constructor -- we'll try to find one.
47
+ if [:before_constructor, :check_more].include?(state)
48
+ # checking more and newline? -> done
49
+ if token.is_a?(RubyToken::TkNL) and state == :check_more
50
+ state = :done
51
+ break
52
+ end
53
+ # token is Proc?
54
+ if token.is_a?(RubyToken::TkCONSTANT) and
55
+ token.instance_variable_get(:@name) == "Proc"
56
+ # method call?
57
+ if lexer.token.is_a?(RubyToken::TkDOT)
58
+ method = lexer.token
59
+ # constructor?
60
+ if method.is_a?(RubyToken::TkIDENTIFIER) and
61
+ method.instance_variable_get(:@name) == "new"
62
+ unless state == :check_more
63
+ # okay, code will follow soon.
64
+ state = :before_code
65
+ else
66
+ # multiple procs on one line
67
+ return
68
+ end
69
+ end
70
+ end
71
+ # token is lambda or proc call?
72
+ elsif token.is_a?(RubyToken::TkIDENTIFIER) and
73
+ %w{proc lambda}.include?(token.instance_variable_get(:@name))
74
+ unless state == :check_more
75
+ # okay, code will follow soon.
76
+ state = :before_code
77
+ else
78
+ # multiple procs on one line
79
+ return
80
+ end
81
+ end
82
+
83
+ # we're waiting for the code start to appear.
84
+ elsif state == :before_code
85
+ if token.is_a?(RubyToken::TkfLBRACE) or token.is_a?(RubyToken::TkDO)
86
+ # found the code start, update state and remember current token
87
+ state = :in_code
88
+ start_token = token
89
+ end
90
+
91
+ # okay, we're inside code
92
+ elsif state == :in_code
93
+ if token.is_a?(RubyToken::TkRBRACE) or token.is_a?(RubyToken::TkEND)
94
+ nesting_level -= 1
95
+ if nesting_level == 0
96
+ # we're done!
97
+ end_token = token
98
+ # parse another time to check if there are multiple procs on one line
99
+ # we can't handle that case correctly so we return no source code at all
100
+ state = :check_more
101
+ end
102
+ elsif token.is_a?(RubyToken::TkfLBRACE) or token.is_a?(RubyToken::TkDO) or
103
+ token.is_a?(RubyToken::TkBEGIN) or token.is_a?(RubyToken::TkCASE) or
104
+ token.is_a?(RubyToken::TkCLASS) or token.is_a?(RubyToken::TkDEF) or
105
+ token.is_a?(RubyToken::TkFOR) or token.is_a?(RubyToken::TkIF) or
106
+ token.is_a?(RubyToken::TkMODULE) or token.is_a?(RubyToken::TkUNLESS) or
107
+ token.is_a?(RubyToken::TkUNTIL) or token.is_a?(RubyToken::TkWHILE) or
108
+ token.is_a?(RubyToken::TklBEGIN)
109
+ nesting_level += 1
110
+ end
111
+ end
112
+ end
113
+
114
+ if start_token and end_token
115
+ start_line, end_line = start_token.line_no - 1, end_token.line_no - 1
116
+ source = lines[start_line .. end_line]
117
+ start_offset = start_token.char_no
118
+ start_offset += 1 if start_token.is_a?(RubyToken::TkDO)
119
+ end_offset = -(source.last.length - end_token.char_no)
120
+ source.first.slice!(0 .. start_offset)
121
+ source.last.slice!(end_offset .. -1)
122
+
123
+ # Can't use .strip because newline at end of code might be important
124
+ # (Stuff would break when somebody does proc { ... #foo\n})
125
+ proc.source = source.join.gsub(/^ | $/, "")
126
+ end
127
+ end
128
+
129
+ module_function :handle, :get_lines
130
+ end
@@ -0,0 +1,79 @@
1
+ class Sproc < Proc
2
+
3
+ class << self
4
+ # An alternate constructor for the class, to allow string input.
5
+ def build(arg=nil, &block)
6
+ block_given? ? infer_sproc(block) : infer_sproc(arg)
7
+ end
8
+
9
+ def infer_sproc(arg)
10
+ case arg
11
+ when Proc
12
+ Proc.new(&arg)
13
+ when String
14
+ Sproc.from_string(arg)
15
+ else
16
+ raise ArgumentError, "Don't know how to create a sproc from #{arg.inspect}"
17
+ end
18
+ end
19
+ protected :infer_sproc
20
+ end
21
+
22
+ def source_descriptor
23
+ if md = /^#<Proc:0x[0-9A-Fa-f]+@(.+):(\d+)>$/.match(old_inspect)
24
+ filename, line = md.captures
25
+ return filename, line.to_i
26
+ end
27
+ end
28
+
29
+ attr_accessor :source
30
+ def source
31
+ ProcSource.handle(self) unless @source
32
+ @source
33
+ end
34
+
35
+ alias :old_inspect :inspect
36
+ def inspect
37
+ if source
38
+ "sproc {#{source}}"
39
+ else
40
+ old_inspect
41
+ end
42
+ end
43
+
44
+ def ==(other)
45
+ if self.source and other.source
46
+ self.source == other.source
47
+ else
48
+ self.object_id == other.object_id
49
+ end
50
+ end
51
+
52
+ def _dump(depth = 0)
53
+ if source
54
+ source
55
+ else
56
+ raise(TypeError, "Can't serialize Proc with unknown source code.")
57
+ end
58
+ end
59
+
60
+ def to_yaml(*args)
61
+ self.source # force @source to be set
62
+ super.sub("object:Proc", "sproc")
63
+ end
64
+
65
+ def self.allocate; from_string ""; end
66
+
67
+ def self.from_string(string)
68
+ result = eval("Sproc.new {#{string}}")
69
+ result.source = string
70
+ return result
71
+ end
72
+
73
+ def self._load(code)
74
+ self.from_string(code)
75
+ end
76
+
77
+ def self.marshal_load; end
78
+ def marshal_load; end
79
+ end
@@ -0,0 +1,25 @@
1
+ if __FILE__ == $0 then
2
+ require "pstore"
3
+
4
+ code = lambda { puts "Hello World!" }
5
+
6
+ File.open("proc.marshalled", "w") { |file| Marshal.dump(code, file) }
7
+ code = File.open("proc.marshalled") { |file| Marshal.load(file) }
8
+
9
+ code.call
10
+
11
+ store = PStore.new("proc.pstore")
12
+ store.transaction do
13
+ store["proc"] = code
14
+ end
15
+ store.transaction do
16
+ code = store["proc"]
17
+ end
18
+
19
+ code.call
20
+
21
+ File.open("proc.yaml", "w") { |file| YAML.dump(code, file) }
22
+ code = File.open("proc.yaml") { |file| YAML.load(file) }
23
+
24
+ code.call
25
+ end
data/lib/sirb/sproc.rb ADDED
@@ -0,0 +1,29 @@
1
+ # This is an adaptation from Florian Groß's submission to Ruby Quiz #38.
2
+ # http://rubyquiz.com/quiz38.html
3
+ #
4
+ # I needed a serializable Proc, I don't care about the closure of
5
+ # the proc. I just need to be able to store procs between Sirb sessions.
6
+ # I'm using these procs with explicitly-passed context anyway, so they
7
+ # are meant to be portable functions.
8
+
9
+ # Loads everything in Sproc, want to break this up, make it more useful
10
+ # and understandable.
11
+ Dir.glob("#{File.dirname(__FILE__)}/sproc/*.rb").each { |file| require file }
12
+
13
+ require 'yaml'
14
+ YAML.add_ruby_type(/^proc/) do |type, val|
15
+ Proc.from_string(val["source"])
16
+ end
17
+
18
+ EVAL_LINES__ = Hash.new
19
+
20
+ alias :old_eval :eval
21
+ def eval(code, *args)
22
+ context, descriptor, start_line, *more = *args
23
+ descriptor ||= "(eval#{code.hash})"
24
+ start_line ||= 0
25
+ lines ||= code.grep(/.*/)
26
+ EVAL_LINES__[descriptor] ||= Array.new
27
+ EVAL_LINES__[descriptor][start_line, lines.length] = lines
28
+ old_eval(code, context, descriptor, start_line, *more)
29
+ end
@@ -0,0 +1,20 @@
1
+ module Sirb #:nodoc:
2
+
3
+ # This adds some concurrency and distributed processing to your programs.
4
+ # It follows loosely the interface offered by Erlang though the implementation
5
+ # is different:
6
+ # * spawn
7
+ # * send
8
+ # * receive
9
+ # * link
10
+ # * system_process
11
+ # * spawn_link
12
+ # * disconnect_node
13
+ # * monitor_node
14
+ # * node
15
+ # * nodes
16
+ # * is_alive
17
+ module ThreadSupport
18
+
19
+ end
20
+ end
@@ -0,0 +1,5 @@
1
+ # Also from The Ruby Programming Language.
2
+ class UnboundMethod
3
+ # Allow [] as an alternative to bind.
4
+ alias [] bind
5
+ end
data/lib/sirb.rb ADDED
@@ -0,0 +1,52 @@
1
+ $:.unshift(File.expand_path(File.dirname(__FILE__)))
2
+
3
+ module Sirb
4
+ end
5
+
6
+ require 'sirb/lib_loader'
7
+
8
+ Dir.glob("#{File.dirname(__FILE__)}/overrides/*.rb").each { |file| require file }
9
+
10
+ require 'rubygems'
11
+ LibLoader.add_lib('rubygems')
12
+ LibLoader.add_lib('mathn')
13
+ LibLoader.add_lib('bigdecimal') {
14
+ require 'bigdecimal'
15
+ require 'bigdecimal/math'
16
+ }
17
+ LibLoader.add_lib('set')
18
+ LibLoader.add_lib('matrix')
19
+ LibLoader.add_lib('narray')
20
+ LibLoader.add_lib('rnum')
21
+ LibLoader.add_lib('rgl') {
22
+ require 'rgl/dot'
23
+ require 'rgl/adjacency'
24
+ require 'rgl/traversal'
25
+ require 'rgl/topsort'
26
+ }
27
+ LibLoader.add_lib('tenacious_g')
28
+ LibLoader.add_lib('rbtree')
29
+ LibLoader.add_lib('statisticus')
30
+
31
+
32
+ LibLoader.add_lib('general statistics') {
33
+ require 'sirb/general_statistics'
34
+ include Sirb::GeneralStatistics
35
+ }
36
+
37
+ LibLoader.add_lib('enumerable statistics') {
38
+ require 'sirb/enumerable_statistics'
39
+ class Array
40
+ include Sirb::EnumerableStatistics
41
+ end
42
+ # TODO: Add other enumerables, adapt for Matrices, Vectors, graphs, the whole thing.
43
+
44
+ require 'sirb/inter_enumerable_statistics'
45
+ include Sirb::InterEnumerableStatistics
46
+
47
+ require 'sirb/functional'
48
+ require 'sirb/unbound_method'
49
+
50
+ }
51
+
52
+ puts LibLoader.to_s if LibLoader.to_s
@@ -0,0 +1,10 @@
1
+ # Called after sirb.rb, when we want to have stored procedures. Sproc/
2
+ # Proc is pretty draconian, so I want to pull this out for now until
3
+ # more tests have been done. Probably we'll never want the command runner
4
+ # if Sirb is being used as a library, instead of as a real Irb instance.
5
+
6
+ LibLoader.add_lib('command runner') {
7
+ require 'sirb/sproc'
8
+ require 'sirb/runner'
9
+ include Sirb::CommandLineMethods
10
+ }
@@ -0,0 +1,7 @@
1
+ require File.join(File.dirname(__FILE__), "/../../spec_helper")
2
+
3
+ describe Array do
4
+ it "should allow multiple paramaters for include?" do
5
+ [1,2,3].include?(1,2).should eql(true)
6
+ end
7
+ end