Advertisement
Guest User

Untitled

a guest
Oct 23rd, 2019
278
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.26 KB | None | 0 0
  1. # encoding: utf-8
  2.  
  3. if defined?(Encoding) then
  4. Encoding.default_external = 'utf-8'
  5. Encoding.default_internal = 'utf-8'
  6. else
  7. $KCODE = 'utf-8'
  8. end
  9. ENV["LANG"] = 'en_US.UTF-8'
  10.  
  11. begin
  12. # Compatibility stuff
  13. unless IRB.conf[:AT_EXIT]
  14. IRB.conf[:AT_EXIT] = []
  15. Kernel.at_exit do
  16. IRB.conf[:AT_EXIT].each do |hook|
  17. hook.call
  18. end
  19. end
  20. end
  21.  
  22. ## Some stuff I commonly use
  23. # Ok, I usually hate that and prefer plain requires, but due to begin/rescue for each of it, I'll do it this way
  24. %w[
  25. pp
  26. awesome_print
  27. yaml
  28. enumerator
  29. readline
  30. ].each do |path|
  31. begin
  32. require path
  33. rescue LoadError
  34. warn "Failed to load #{path.inspect} in #{__FILE__}:#{__LINE__-2}" if $VERBOSE
  35. end
  36. end
  37.  
  38.  
  39.  
  40. module IRBUtilities; module_function
  41. MethodMethod = Object.instance_method(:method)
  42. MethodInstanceMethod = Module.instance_method(:instance_method)
  43. MethodIsA = Object.instance_method(:is_a?)
  44. MethodIsDescendant = Module.instance_method(:<)
  45.  
  46. def self._method(obj, *args, &block)
  47. MethodMethod.bind(obj).call(*args, &block)
  48. end
  49.  
  50. def self._instance_method(obj, *args, &block)
  51. MethodInstanceMethod.bind(obj).call(*args, &block)
  52. end
  53.  
  54. def self._is_a?(obj, klass)
  55. MethodIsA.bind(obj).call(klass)
  56. end
  57.  
  58. def self._is_descendant?(obj, klass)
  59. MethodIsDescendant.bind(obj).call(klass)
  60. end
  61.  
  62. def pretty_print_methods(obj, meths)
  63. descs = meths.map { |n, m|
  64. i = 0
  65. params = m.parameters.map { |type, name|
  66. case type
  67. when :req then name || "arg#{i+=1}"
  68. when :opt then "#{name || "arg#{i+=1}"}=?"
  69. when :rest then "*#{name || "rest"}"
  70. when :block then "&#{name || "block"}"
  71. else "??"
  72. end
  73. }
  74. [" #{n}(#{params.join(", ")})", m.source_location ? m.source_location.join(':') : '[native]']
  75. }
  76. width = descs.map { |a,b| a.size }.max
  77. descs.each do |a,b|
  78. $stdout.printf "%-*s %s\n", width, a, b
  79. end
  80.  
  81. descs.size
  82. end
  83. end
  84.  
  85.  
  86.  
  87. ## Load history
  88. module IRBHistory
  89. @history_file = File.expand_path('~/.irb_session_history')
  90. @max_sessions = 20
  91. @max_lines_per_session = 1000
  92. @max_lines = 10000
  93. @sessions = {}
  94. @history = []
  95. @current_history = nil
  96.  
  97. @current_wd = File.expand_path('.')
  98. @current_ruby = "#{defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'}-#{RUBY_VERSION}".gsub(/\s+/, '_')
  99. @current_ppid = Process.ppid
  100. @current_key = [@current_ppid, @current_wd, @current_ruby]
  101.  
  102. class <<self
  103. attr_reader :sessions, :history_file, :history, :current_history
  104. attr_reader :max_sessions, :max_lines_per_session, :max_lines
  105. attr_reader :current_wd, :current_ruby, :current_ppid, :current_key
  106. end
  107.  
  108. def self.push(line)
  109. @current_history.push([Time.now.to_i, line])
  110. @current_history.shift if @current_history.length > @max_lines
  111. end
  112.  
  113. def self.restore
  114. read_history_log
  115. restore_history
  116. restore_readline_history
  117. end
  118.  
  119. def self.read_history_log
  120. sessions = {}
  121. lost = []
  122.  
  123. current = lost
  124. if File.exist?(@history_file) then
  125. File.foreach(@history_file).each_with_index do |line, line_no|
  126. if /^\# session time=(\d+), ppid=(\d+), ruby=(\S+), cwd=(.*)$/ =~ line then
  127. time, ppid, ruby, cwd = $1, $2, $3, $4
  128. current.replace(current.first(@max_lines_per_session)) # truncate array
  129. time = time.to_i
  130. ppid = ppid.to_i
  131. current = []
  132. session_key = [ppid, cwd, ruby]
  133. sessions[session_key] = [time, current]
  134. elsif /^(\d+) (.*)$/ =~ line then
  135. time, code = $1, $2
  136. current << [time.to_i, code]
  137. else
  138. warn "Malformed line #{line_no+1}: #{line.inspect}"
  139. end
  140. end
  141. warn "#{lost.size} log lines without session" unless lost.empty?
  142. current.replace(current.first(@max_lines_per_session)) # truncate array
  143. end
  144.  
  145. sessions[@current_key] ||= [Time.now.to_i, []]
  146. sorted = sessions.sort_by { |key, (time, lines)| time }
  147. @sessions = Hash[sorted.last(@max_sessions)]
  148. @current_history = @sessions[@current_key] ? @sessions[@current_key].last : []
  149. nil
  150. end
  151.  
  152. def self.restore_history
  153. @history = []
  154. @sessions.sort_by { |(ppid, cwd, ruby), (time, lines)|
  155. [
  156. ppid == @current_ppid ? 1 : 0, # matching ppid later (latest means first in history)
  157. cwd == @current_wd ? 1 : 0, # matching working directory later
  158. time # newer ones later
  159. ]
  160. # }.select { |(ppid, cwd, ruby), (time, lines)|
  161. # ruby == @current_ruby
  162. }.each do |(ppid, cwd, ruby), (time, lines)|
  163. @history.concat(lines)
  164. end
  165. @history.replace(@history.first(@max_lines)) # truncate
  166. end
  167.  
  168. def self.restore_readline_history
  169. Readline::HISTORY.clear
  170. Readline::HISTORY.push(*@history.map(&:last))
  171. end
  172.  
  173. def self.save
  174. return unless @current_history
  175. save_history = @current_history.first(@max_lines_per_session)
  176. @sessions.replace({@current_key => [Time.now.to_i, save_history]}.merge(@sessions))
  177. File.open(@history_file, 'a+:binary') do |fh|
  178. fh.flock(File::LOCK_EX)
  179. fh.truncate(0)
  180. @sessions.each do |(ppid, cwd, ruby), (time, lines)|
  181. fh.puts "\# session time=#{time}, ppid=#{ppid}, ruby=#{ruby}, cwd=#{cwd}"
  182. lines.each do |line_time, line|
  183. fh.puts("#{line_time} #{line}")
  184. end
  185. end
  186. end
  187. end
  188.  
  189. # utility function
  190. def self.sort_hash_by!(hash, &block)
  191. hash.replace(Hash[hash.sort_by(&block)])
  192. end
  193. end
  194.  
  195. if defined? Readline then
  196. # Compat
  197. unless Readline::HISTORY.respond_to? :clear
  198. hist = Readline::HISTORY
  199. def hist.clear
  200. length.times do pop end
  201. end
  202. end
  203. IRBHistory.restore
  204. IRB.conf[:AT_EXIT] << proc { IRBHistory.save }
  205.  
  206. module IRB
  207. begin
  208. require "readline"
  209. ::NBSP = "\302\240"
  210. require 'irb/completion'
  211. class ReadlineInputMethod < InputMethod
  212. def gets
  213. if l = readline(@prompt, false)
  214. l.gsub!(/\302\240/, "") # this line does the trick - it's for poor swiss people who have {|} on opt-<key> combo, which means that pressing opt too early or releasing it too late you generate a non-breaking space (opt-space) which causes a syntax error
  215. HISTORY.push(l) unless l.empty?
  216. IRBHistory.push(l)
  217. @line[@line_no += 1] = "#{l}\n"
  218. else
  219. @eof = true
  220. l
  221. end
  222. end
  223. end
  224. Readline.completion_append_character = ""
  225. rescue LoadError
  226. end
  227. end
  228. end
  229.  
  230.  
  231.  
  232. ## A couple of core patches to make life in IRB a little bit nicer
  233. alias q exit
  234.  
  235. module OriginalInspect
  236. def irb_inspect
  237. inspect
  238. end
  239.  
  240. def self.wrap(klass)
  241. klass.class_eval do
  242. alias original_inspect inspect
  243.  
  244. def inspect
  245. r = original_inspect
  246. r.extend OriginalInspect
  247. r
  248. end
  249. end
  250. end
  251. end
  252. class Object
  253. def eigenclass
  254. class<<self;self;end
  255. end
  256. def eigendef(*a,&b)
  257. eigenclass.send(:define_method, *a, &b)
  258. end
  259. def __m
  260. meths = methods-Object.instance_methods
  261. meths -= Enumerable.instance_methods if IRBUtilities._is_a?(self, Enumerable)
  262.  
  263. meths.sort
  264. end
  265. if Method.method_defined? :parameters then
  266. def __mx
  267. IRBUtilities.pretty_print_methods(self, __m.map { |m| [m, IRBUtilities._method(self, m)] })
  268. end
  269. else
  270. def __mx
  271. warn "__mx requires Method#parameters"
  272. __m
  273. end
  274. end
  275. def i
  276. $stdout.puts inspect
  277. self
  278. end
  279. def ii
  280. $stdout.puts pretty_inspect
  281. self
  282. end
  283. def irb_inspect
  284. original = inspect
  285. if original.length > 100 then
  286. $stdout.sprintf "#<%p %s>", self.class, instance_variables.join(" ")
  287. else
  288. original
  289. end
  290. rescue
  291. "<<could not inspect object>>"
  292. end
  293. end
  294. class Module
  295. def __im
  296. meths = instance_methods-Object.instance_methods
  297. meths -= Enumerable.instance_methods if IRBUtilities._is_descendant?(self, Enumerable)
  298.  
  299. meths.sort
  300. end
  301. if Method.method_defined? :parameters then
  302. def __imx
  303. IRBUtilities.pretty_print_methods(self, __im.map { |m| [m, IRBUtilities._instance_method(self, m)] })
  304. end
  305. else
  306. def __imx
  307. warn "__imx requires Method#parameters"
  308. __im
  309. end
  310. end
  311. def __m
  312. if self.equal?(Module)
  313. super
  314. else
  315. meths = methods-Module.methods
  316. meths -= Enumerable.instance_methods if IRBUtilities._is_a?(self, Enumerable)
  317.  
  318. meths.sort
  319. end
  320. end
  321. end
  322. class String
  323. # Convenience method, see Regexp#show_match
  324. def show_match(regex)
  325. regex.show_match(self)
  326. end
  327.  
  328. OriginalInspect.wrap(self)
  329. # def irb_inspect
  330. # if length <= 100 then
  331. # original_inspect
  332. # else
  333. # sub(/\A(.{89}).*(.{10})/m, '\1…\2').original_inspect
  334. # end
  335. # end
  336. end
  337. class Array
  338. OriginalInspect.wrap(self)
  339. def irb_inspect
  340. if size <= 100 then
  341. "[#{map(&:irb_inspect).join(', ')}]"
  342. else
  343. "[#{first(89).map(&:irb_inspect).join(', ')}, …, #{last(10).map(&:irb_inspect).join(', ')}]"
  344. end
  345. end
  346. end
  347. class Hash
  348. OriginalInspect.wrap(self)
  349. def irb_inspect
  350. if size <= 100 then
  351. "{#{map{|k,v| "#{k.irb_inspect} => #{v.irb_inspect}"}.join(', ')}}"
  352. else
  353. ary = to_a
  354. "{#{ary.first(89).map{|k,v| "#{k.irb_inspect} => #{v.irb_inspect}"}.join(', ')}, …, " \
  355. "#{ary.last(10).map{|k,v| "#{k.irb_inspect} => #{v.irb_inspect}"}.join(', ')}}"
  356. end
  357. end
  358. end
  359. module Enumerable
  360. def __m
  361. (methods-Object.methods-Enumerable.instance_methods).sort
  362. end
  363. end
  364. module Kernel
  365. module_function
  366. # Prints memory and cpu footprint of the server (uses ps in a subshell,
  367. # portability is therefore limited)
  368. def print_resource_usage
  369. ps_out = `ps -o vsz,rss,%cpu,%mem -p #{$$}`
  370. vsz, rss, cpu, pmem = ps_out.scan(/\d+(?:[.,]\d+)?/).map { |e| e.gsub(/,/,'.').to_f } # ps on 10.5.1 outputs ',' instead of '.' for MEM%
  371. virtual, real = (vsz-rss).div(1024), rss.div(1024)
  372. $stdout.printf "%dMB real, %dMB virtual, %.1f%% CPU, %.1f%% MEM\n", real, virtual, cpu, pmem
  373. end
  374.  
  375. # Terminate the current process - the hard way
  376. def t!
  377. `kill -9 #{$$}`
  378. end
  379.  
  380. # write data to a file
  381. def putf(content, path='~/Desktop/irb_dump.txt')
  382. File.open(File.expand_path(path), 'w') { |fh| fh.write(content) }
  383. end
  384.  
  385. # tiny bench method
  386. def bench(n=100, runs=10)
  387. n = n.to_i
  388. t = []
  389. runs.times do
  390. a = Time.now
  391. for i in 1..n
  392. yield
  393. end
  394. t << (Time.now-a)*1000/n
  395. end
  396. mean = t.inject { |a,b| a+b }.quo(t.size)
  397. stddev = t.map { |a| (a-mean)**2 }.inject { |a,b| a+b }.quo(t.size)**0.5
  398. [mean, stddev]
  399. end
  400.  
  401. # tiny bench method with nice printing
  402. def pbench(n=1, runs=5, &b)
  403. m, s = *bench(n,runs,&b)
  404. p = (100.0*s)/m
  405. $stdout.printf "ø %fms (%.1f%%)\n", m, p
  406. end
  407.  
  408. # tiny bench method with nice printing,
  409. # runs multiple tests
  410. def mbench(n, runs, benches)
  411. label_width = benches.keys.max_by(&:length).length+1
  412. measures = []
  413. benches.each do |label, b|
  414. m, s = *bench(n,runs,&b)
  415. p = (100.0*s)/m
  416. measures << [label, m]
  417. $stdout.printf "%-*s ø %fms (%.1f%%)\n", label_width, "#{label}:", m, p
  418. end
  419.  
  420. measures.sort_by! { |l,m| m }
  421. rel = measures.first.last
  422. $stdout.puts measures.map { |l,m| sprintf "%s: %.1f", l, m/rel }.join(', ')
  423. nil
  424. end
  425.  
  426. module PasswordString
  427. def inspect; "[PASSWORD]"; end
  428. def to_s; "[PASSWORD]"; end
  429. def dup; obj=super;obj.extend PasswordString; obj; end
  430. def clone; obj=super;obj.extend PasswordString; obj; end
  431. end
  432.  
  433. def password
  434. `stty -echo`
  435. r = gets.chomp
  436. r.extend PasswordString
  437. r
  438. ensure
  439. `stty echo`
  440. end
  441. alias secret password
  442.  
  443. # 1.9's p/pp return the arguments -> sucks in irb. let it return nil again.
  444. def p(*args)
  445. puts(args.map{|a|a.inspect})
  446. nil
  447. end
  448. def pp(*args)
  449. PP.pp(*args)
  450. nil
  451. end
  452.  
  453. # Invoke an original method on an object that possibly overrides, fakes or removes it
  454. # Example:
  455. # cm some_obj, :inspect, Object
  456. # Object.instance_method(:inspect).bind(some_obj).call # is what that does
  457. def cm(obj, meth, klass=Object)
  458. klass.instance_method(meth).bind(obj).call
  459. end
  460. end
  461.  
  462. class Regexp
  463. # Convenience method on Regexp so you can do
  464. # /an/.show_match("banana") # => "b<<an>>ana"
  465. def show_match(str)
  466. self =~ str
  467.  
  468. "#{$`}<<#{$&}>>#{$'}"
  469. end
  470. end
  471.  
  472.  
  473. # Support methods for beedit
  474. require 'shellwords'
  475. module ::BBedit
  476. def self.open(obj)
  477. case obj
  478. when ::String
  479. `bbedit #{obj.shellescape}`
  480. when ::Method, ::UnboundMethod
  481. file, line = obj.source_location
  482. if file && File.readable?(file) then
  483. `bbedit #{file.shellescape}:#{line}`
  484. else
  485. "Can't open native method"
  486. end
  487. end
  488. end
  489. end
  490. module ::Sublime
  491. def self.open(obj)
  492. case obj
  493. when ::String
  494. `subl #{obj.shellescape}`
  495. when ::Method, ::UnboundMethod
  496. file, line = obj.source_location
  497. if file && File.readable?(file) then
  498. `subl #{file.shellescape}:#{line}`
  499. else
  500. "Can't open native method"
  501. end
  502. end
  503. end
  504. end
  505. class ::Method
  506. def bbedit
  507. BBedit.open(self)
  508. end
  509. def subl
  510. Sublime.open(self)
  511. end
  512. end
  513. class ::UnboundMethod
  514. def bbedit
  515. BBedit.open(self)
  516. end
  517. def subl
  518. Sublime.open(self)
  519. end
  520. end
  521. class ::Object
  522. def bbedit(name)
  523. method(name).bbedit
  524. end
  525. def subl(name)
  526. method(name).subl
  527. end
  528. end
  529.  
  530.  
  531.  
  532. ## Configure IRB
  533. ruby = ENV["rvm_ruby_string"] || "#{defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'}-#{RUBY_VERSION}"
  534. prompt = {
  535. :PROMPT_I => "\001\e[42m\002 \001\e[0m\002 #{ruby}:%03n:%i>> ", # default prompt
  536. :PROMPT_S => "\001\e[42m\002 \001\e[0m\002 #{ruby}:%03n:%i%l> ", # known continuation
  537. :PROMPT_C => "\001\e[42m\002 \001\e[0m\002 #{ruby}:%03n:%i>> ",
  538. :PROMPT_N => "\001\e[42m\002 \001\e[0m\002 #{ruby}:%03n:%i*> ", # unknown continuation
  539. :RETURN => "\001\e[42m\002 \001\e[0m\002 # => %s\n",
  540. }
  541. #IRB.conf[:INSPECT_MODE] = "{ |obj| obj.irb_inspect }" # use that code to generate the reply-line
  542. IRB.conf[:INSPECT_MODE] = :inspect
  543. IRB.conf.delete(:AUTO_INDENT) # irb checks for presence, not content... stupid
  544. IRB.conf[:PROMPT][:APEIROS] = prompt
  545. IRB.conf[:PROMPT_MODE] = :APEIROS
  546.  
  547. ## Load railsrc
  548. if defined?(Rails) then
  549. rails_rc = File.expand_path('~/.railsrc')
  550. load rails_rc if File.exist?(rails_rc)
  551. end
  552.  
  553. rescue => e
  554. $stdout.puts e, *e.backtrace.first(5)
  555. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement