utils 0.2.4 → 0.6.4

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.
@@ -1,30 +1,60 @@
1
1
  require 'tins/xt'
2
2
  require 'irb/completion'
3
3
  require 'enumerator'
4
+ require 'tempfile'
4
5
  require 'pp'
5
6
  require_maybe 'ap'
6
7
  if Readline.respond_to?(:point) && Readline.respond_to?(:line_buffer)
7
8
  require 'pry-editline'
8
9
  end
9
10
  require 'utils'
10
- require 'drb'
11
11
 
12
12
  $editor = Utils::Editor.new
13
13
  $pager = ENV['PAGER'] || 'less -r'
14
14
 
15
15
  module Utils
16
16
  module IRB
17
+ require 'utils/irb/service'
17
18
 
18
19
  module Shell
19
20
  require 'fileutils'
20
21
  include FileUtils
21
22
  include Tins::Find
22
23
 
24
+ def receiver_unless_main(method, &block)
25
+ receiver_name = method.receiver.to_s
26
+ if receiver_name != 'main'
27
+ if block
28
+ block.(receiver_name)
29
+ else
30
+ receiver_name
31
+ end
32
+ end
33
+ end
34
+ private :receiver_unless_main
35
+
23
36
  # Start _ri_ for +pattern+. If +pattern+ is not string like, call it with
24
37
  # pattern.class.name as argument.
25
- def ri(*patterns)
26
- patterns.map! { |p| p.respond_to?(:to_str) ? p.to_str : p.class.name }
27
- system "ri #{patterns.map { |p| "'#{p}'" } * ' '} | #{$pager}"
38
+ def ri(*patterns, doc: 'ri')
39
+ patterns.empty? and
40
+ receiver_unless_main(method(__method__)) do |pattern|
41
+ return ri(pattern, doc: doc)
42
+ end
43
+ patterns.map! { |p|
44
+ case
45
+ when Module === p
46
+ p.name
47
+ when p.respond_to?(:to_str)
48
+ p.to_str
49
+ else
50
+ p.class.name
51
+ end
52
+ }
53
+ system "#{doc} #{patterns.map { |p| "'#{p}'" } * ' ' } | #$pager"
54
+ end
55
+
56
+ def yri(*patterns)
57
+ ri *patterns, doc: 'yri'
28
58
  end
29
59
 
30
60
  # Restart this irb.
@@ -32,53 +62,70 @@ module Utils
32
62
  exec $0
33
63
  end
34
64
 
65
+ def irb_open(url = nil, &block)
66
+ case
67
+ when url
68
+ system 'open', url
69
+ when block
70
+ Tempfile.open('wb') do |t|
71
+ t.write capture_output(&block)
72
+ t.rewind
73
+ system 'open', t.path
74
+ end
75
+ when url = receiver_unless_main(method(__method__))
76
+ irb_open url
77
+ else
78
+ raise ArgumentError, 'need an url or block'
79
+ end
80
+ end
81
+
35
82
  # Start an irb server.
36
- def irb_server(hostname = nil, port = nil)
37
- Utils::IRB::Service.start(hostname, port) {}
83
+ def irb_server(uri = nil)
84
+ Utils::IRB::Service.start(uri) {}
38
85
  end
39
86
 
40
87
  # Connect to an irb server.
41
- def irb_connect(hostname = nil, port = nil)
42
- Utils::IRB::Service.connect(hostname, port)
88
+ def irb_connect(uri = nil)
89
+ Utils::IRB::Service.connect(uri)
43
90
  end
44
91
 
45
92
  # TODO: change the API of this stuff
46
93
 
47
94
  # Return all instance methods of obj's class.
48
- def irb_all_class_instance_methods(obj)
95
+ def irb_all_class_instance_methods(obj = self)
49
96
  methods = obj.class.instance_methods
50
97
  irb_wrap_methods obj, methods
51
98
  end
52
99
 
53
100
  # Return instance methods of obj's class without the inherited/mixed in
54
101
  # methods.
55
- def irb_class_instance_methods(obj)
102
+ def irb_class_instance_methods(obj = self)
56
103
  methods = obj.class.instance_methods(false)
57
104
  irb_wrap_methods obj, methods
58
105
  end
59
106
 
60
107
  # Return all instance methods defined in module modul.
61
- def irb_all_instance_methods(modul)
108
+ def irb_all_instance_methods(modul = self)
62
109
  methods = modul.instance_methods
63
110
  irb_wrap_methods modul, methods, true
64
111
  end
65
112
 
66
113
  # Return instance methods defined in module modul without the inherited/mixed
67
114
  # in methods.
68
- def irb_instance_methods(modul)
115
+ def irb_instance_methods(modul = self)
69
116
  methods = modul.instance_methods(false)
70
117
  irb_wrap_methods modul, methods, true
71
118
  end
72
119
 
73
120
  # Return all methods of obj (including obj's eigenmethods.)
74
- def irb_all_methods(obj)
121
+ def irb_all_methods(obj = self)
75
122
  methods = obj.methods
76
123
  irb_wrap_methods obj, methods
77
124
  end
78
125
 
79
126
  # Return instance methods of obj's class without the inherited/mixed in
80
127
  # methods, but including obj's eigenmethods.
81
- def irb_methods(obj)
128
+ def irb_methods(obj = self)
82
129
  methods = obj.class.ancestors[1..-1].inject(obj.methods) do |all, a|
83
130
  all -= a.instance_methods
84
131
  end
@@ -86,23 +133,16 @@ module Utils
86
133
  end
87
134
 
88
135
  # Return all eigen methods of obj.
89
- def irb_eigen_methods(obj)
136
+ def irb_eigen_methods(obj = self)
90
137
  irb_wrap_methods obj, obj.methods(false)
91
138
  end
92
139
 
93
- def irb_wrap_methods(obj, methods, modul = false)
140
+ def irb_wrap_methods(obj = self, methods = methods(), modul = false)
94
141
  methods.map do |name|
95
142
  MethodWrapper.new(obj, name, modul) rescue nil
96
143
  end.compact.sort!
97
144
  end
98
145
 
99
- def irb_clipboard
100
- case RUBY_PLATFORM
101
- when /darwin/
102
- 'reattach-to-user-namespace pbcopy'
103
- end
104
- end
105
-
106
146
  class WrapperBase
107
147
  include Comparable
108
148
 
@@ -147,7 +187,7 @@ module Utils
147
187
  def initialize(obj, name, modul)
148
188
  super(name)
149
189
  @method = modul ? obj.instance_method(name) : obj.method(name)
150
- @description = "#{owner}##@name(#{arity})"
190
+ @description = @method.description(style: :namespace)
151
191
  end
152
192
 
153
193
  attr_reader :method
@@ -180,12 +220,12 @@ module Utils
180
220
  end
181
221
 
182
222
  # Return all the constants defined in +modul+.
183
- def irb_constants(modul)
223
+ def irb_constants(modul = self)
184
224
  modul.constants.map { |c| ConstantWrapper.new(modul.const_get(c), c) }.sort
185
225
  end
186
226
 
187
227
  # Return all the subclasses of +klass+. TODO implement subclasses w/out rails
188
- def irb_subclasses(klass)
228
+ def irb_subclasses(klass = self)
189
229
  klass.subclasses.map { |c| ConstantWrapper.new(eval(c), c) }.sort
190
230
  end
191
231
 
@@ -193,76 +233,7 @@ module Utils
193
233
  Infinity = 1.0 / 0 # I like to define the infinite.
194
234
  end
195
235
 
196
- # Output all kinds of information about +obj+. If detailed is given output
197
- # details about the methods (+ arity) in inheritance chain of +obj+ as well.
198
- # * detailed as 0 output instance methods only of part 0 (the first) of the
199
- # chain.
200
- # * detailed as 1..2 output instance methods of +obj+ inherited from parts 1
201
- # and 2 of the the chain.
202
- def irb_info(obj, detailed = nil)
203
- if Module === obj
204
- modul = obj
205
- klassp = Class === modul
206
- if klassp
207
- begin
208
- allocated = modul.allocate
209
- rescue TypeError
210
- else
211
- obj = allocated
212
- end
213
- end
214
- else
215
- modul = obj.class
216
- end
217
- inspected = obj.inspect
218
- puts "obj = #{inspected.size > 40 ? inspected[0, 40] + '...' : inspected} is of class #{obj.class}."
219
- am = irb_all_methods(obj).size
220
- ms = irb_methods(obj).size
221
- ems = irb_eigen_methods(obj).size
222
- puts "obj: #{am} methods, #{ms} only local#{ems > 0 ? " (#{ems} eigenmethods),": ','} #{am - ms} inherited/mixed in."
223
- acim = irb_all_class_instance_methods(obj).size
224
- cim = irb_class_instance_methods(obj).size
225
- puts "obj: #{acim} instance methods, #{cim} local, #{acim - cim} only inherited/mixed in."
226
- if klassp
227
- s = modul.superclass
228
- puts "Superclass of #{modul}: #{s}"
229
- end
230
- a = []
231
- ec = true
232
- begin
233
- a << (class << obj; self; end)
234
- rescue TypeError
235
- ec = false
236
- end
237
- a.concat modul.ancestors
238
- if ec
239
- puts "Ancestors of #{modul}: (#{a[0]},) #{a[1..-1].map { |k| "#{k}#{k == s ? '*' : ''}" } * ', '}"
240
- else
241
- puts "Ancestors of #{modul}: #{a[0..-1].map { |k| "#{k}#{k == s ? '*' : ''}" } * ', '}"
242
- end
243
- if Class === modul and detailed
244
- if detailed.respond_to? :to_int
245
- detailed = detailed..detailed
246
- end
247
- detailed.each do |i|
248
- break if i >= a.size
249
- k = a[i]
250
- puts "#{k}:"
251
- puts irb_wrap_methods(obj, k.instance_methods(false)).sort
252
- end
253
- end
254
- nil
255
- end
256
-
257
- # Output *all* the irb_info about +obj+. You may need to buy a bigger screen for
258
- # this or use:
259
- # less { irb_fullinfo object }
260
- def irb_fullinfo(obj)
261
- irb_info obj, 0..Infinity
262
- end
263
-
264
236
  def capture_output(with_stderr = false)
265
- return "missing block" unless block_given?
266
237
  require 'tempfile'
267
238
  begin
268
239
  old_stdout, $stdout = $stdout, Tempfile.new('irb')
@@ -319,8 +290,12 @@ module Utils
319
290
  end
320
291
  end
321
292
 
322
- def irb_write(filename, text = nil)
323
- File.secure_write filename, text, 'wb'
293
+ def irb_write(filename, text = nil, &block)
294
+ if text.nil? && block
295
+ File.secure_write filename, nil, 'wb', &block
296
+ else
297
+ File.secure_write filename, text, 'wb'
298
+ end
324
299
  end
325
300
 
326
301
  def irb_read(filename, chunk_size = 8_192)
@@ -367,6 +342,10 @@ module Utils
367
342
  $editor.full?(:edit, *files)
368
343
  end
369
344
 
345
+ def edit
346
+ $editor.full?(:edit, self)
347
+ end
348
+
370
349
  # List contents of directory
371
350
  def ls(*args)
372
351
  puts `ls #{args.map { |x| "'#{x}'" } * ' '}`
@@ -388,25 +367,6 @@ module Utils
388
367
  end
389
368
  end
390
369
 
391
- module Module
392
- # Start +ri+ for +module#pattern+, trying to find a method matching +pattern+
393
- # for all modules in the ancestors chain of this module.
394
- def ri(pattern = nil)
395
- if pattern
396
- pattern = pattern.to_sym.to_s if pattern.respond_to? :to_sym
397
- ancestors.each do |a|
398
- if method = a.instance_methods(false).find { |m| pattern === m }
399
- a = Object if a == Kernel # ri seems to be confused
400
- system "ri #{a}##{method} | #{$pager}"
401
- end
402
- end
403
- else
404
- system "ri #{self} | #{$pager}"
405
- end
406
- return
407
- end
408
- end
409
-
410
370
  module Regexp
411
371
  # Show the match of this Regexp on the +string+.
412
372
  def show_match(string)
@@ -430,59 +390,6 @@ module Utils
430
390
  end
431
391
  end
432
392
 
433
- module Relation
434
- def explain
435
- connection.select_all("EXPLAIN #{to_sql}")
436
- end
437
- end
438
-
439
- module Service
440
- class << self
441
- attr_accessor :hostname
442
-
443
- attr_accessor :port
444
-
445
- def start(hostname = nil, port = nil, &block)
446
- hostname ||= self.hostname
447
- port ||= self.port
448
- block ||= proc {}
449
- uri = "druby://#{hostname}:#{port}"
450
- puts "Starting IRB server listening to #{uri.inspect}."
451
- DRb.start_service(uri, eval('irb_current_working_binding', block.binding))
452
- end
453
-
454
- def connect(hostname = nil, port = nil)
455
- hostname ||= self.hostname
456
- port ||= self.port
457
- uri = "druby://#{hostname}:#{port}"
458
- irb = DRbObject.new_with_uri(uri)
459
- Proxy.new(irb)
460
- end
461
- end
462
-
463
- self.hostname = 'localhost'
464
-
465
- self.port = 6642
466
-
467
- class Proxy
468
- def initialize(irb)
469
- @irb = irb
470
- end
471
-
472
- def eval(code)
473
- @irb.conf.workspace.evaluate nil, code
474
- end
475
-
476
- def load(filename)
477
- unless filename.start_with?('/')
478
- filename = File.expand_path filename
479
- end
480
- @irb.load filename
481
- end
482
- end
483
-
484
- end
485
-
486
393
  def self.configure
487
394
  ::IRB.conf[:SAVE_HISTORY] = 1000
488
395
  if ::IRB.conf[:PROMPT]
@@ -501,12 +408,11 @@ end
501
408
 
502
409
  Utils::IRB.configure
503
410
 
504
-
505
411
  module IRB
506
412
  class Context
507
413
  def init_save_history
508
- unless (class<<@io;self;end).include?(HistorySavingAbility)
509
- @io.extend(HistorySavingAbility)
414
+ unless @io.singleton_class < HistorySavingAbility
415
+ @io.extend HistorySavingAbility
510
416
  end
511
417
  end
512
418
 
@@ -568,12 +474,6 @@ module IRB
568
474
  end
569
475
  end
570
476
 
571
- if defined?(ActiveRecord::Relation) && !ActiveRecord::Relation.method_defined?(:examine)
572
- class ActiveRecord::Relation
573
- include Utils::IRB::Relation
574
- end
575
- end
576
-
577
477
  class String
578
478
  include Utils::IRB::String
579
479
  end
@@ -582,10 +482,6 @@ class Object
582
482
  include Utils::IRB::Shell
583
483
  end
584
484
 
585
- class Module
586
- include Utils::IRB::Module
587
- end
588
-
589
485
  class Regexp
590
486
  include Utils::IRB::Regexp
591
487
  end
@@ -0,0 +1,39 @@
1
+ require 'drb'
2
+
3
+ module Utils::IRB::Service
4
+ class << self
5
+ attr_accessor :hostname
6
+
7
+ attr_accessor :port
8
+
9
+ def start(uri = nil, &block)
10
+ uri ||= "druby://localhost:6642"
11
+ block ||= proc {}
12
+ puts "Starting IRB server listening to #{uri.inspect}."
13
+ DRb.start_service(uri, eval('irb_current_working_binding', block.binding))
14
+ end
15
+
16
+ def connect(uri = nil)
17
+ uri ||= "druby://localhost:6642"
18
+ irb = DRbObject.new_with_uri(uri)
19
+ Proxy.new(irb)
20
+ end
21
+ end
22
+
23
+ class Proxy
24
+ def initialize(irb)
25
+ @irb = irb
26
+ end
27
+
28
+ def eval(code)
29
+ @irb.conf.workspace.evaluate nil, code
30
+ end
31
+
32
+ def load(filename)
33
+ unless filename.start_with?('/')
34
+ filename = File.expand_path filename
35
+ end
36
+ @irb.load filename
37
+ end
38
+ end
39
+ end