utils 0.2.4 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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