pry 0.12.2 → 0.14.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +158 -1
  3. data/LICENSE +1 -1
  4. data/README.md +331 -269
  5. data/bin/pry +5 -0
  6. data/lib/pry/basic_object.rb +8 -4
  7. data/lib/pry/block_command.rb +22 -0
  8. data/lib/pry/class_command.rb +194 -0
  9. data/lib/pry/cli.rb +44 -55
  10. data/lib/pry/code/code_file.rb +28 -24
  11. data/lib/pry/code/code_range.rb +4 -2
  12. data/lib/pry/code/loc.rb +15 -8
  13. data/lib/pry/code.rb +40 -28
  14. data/lib/pry/code_object.rb +40 -38
  15. data/lib/pry/color_printer.rb +47 -46
  16. data/lib/pry/command.rb +166 -369
  17. data/lib/pry/command_set.rb +76 -73
  18. data/lib/pry/command_state.rb +31 -0
  19. data/lib/pry/commands/amend_line.rb +86 -81
  20. data/lib/pry/commands/bang.rb +18 -14
  21. data/lib/pry/commands/bang_pry.rb +15 -11
  22. data/lib/pry/commands/cat/abstract_formatter.rb +23 -18
  23. data/lib/pry/commands/cat/exception_formatter.rb +71 -60
  24. data/lib/pry/commands/cat/file_formatter.rb +55 -49
  25. data/lib/pry/commands/cat/input_expression_formatter.rb +35 -30
  26. data/lib/pry/commands/cat.rb +61 -54
  27. data/lib/pry/commands/cd.rb +40 -35
  28. data/lib/pry/commands/change_inspector.rb +29 -22
  29. data/lib/pry/commands/change_prompt.rb +44 -39
  30. data/lib/pry/commands/clear_screen.rb +16 -10
  31. data/lib/pry/commands/code_collector.rb +148 -133
  32. data/lib/pry/commands/disable_pry.rb +23 -19
  33. data/lib/pry/commands/easter_eggs.rb +19 -30
  34. data/lib/pry/commands/edit/exception_patcher.rb +21 -17
  35. data/lib/pry/commands/edit/file_and_line_locator.rb +34 -23
  36. data/lib/pry/commands/edit.rb +184 -161
  37. data/lib/pry/commands/exit.rb +39 -35
  38. data/lib/pry/commands/exit_all.rb +24 -20
  39. data/lib/pry/commands/exit_program.rb +20 -16
  40. data/lib/pry/commands/find_method.rb +168 -160
  41. data/lib/pry/commands/fix_indent.rb +16 -12
  42. data/lib/pry/commands/help.rb +140 -133
  43. data/lib/pry/commands/hist.rb +151 -150
  44. data/lib/pry/commands/import_set.rb +20 -16
  45. data/lib/pry/commands/jump_to.rb +25 -21
  46. data/lib/pry/commands/list_inspectors.rb +35 -28
  47. data/lib/pry/commands/ls/constants.rb +59 -42
  48. data/lib/pry/commands/ls/formatter.rb +50 -46
  49. data/lib/pry/commands/ls/globals.rb +38 -34
  50. data/lib/pry/commands/ls/grep.rb +17 -13
  51. data/lib/pry/commands/ls/instance_vars.rb +29 -27
  52. data/lib/pry/commands/ls/interrogatable.rb +18 -12
  53. data/lib/pry/commands/ls/jruby_hacks.rb +47 -41
  54. data/lib/pry/commands/ls/local_names.rb +26 -22
  55. data/lib/pry/commands/ls/local_vars.rb +38 -28
  56. data/lib/pry/commands/ls/ls_entity.rb +47 -51
  57. data/lib/pry/commands/ls/methods.rb +44 -43
  58. data/lib/pry/commands/ls/methods_helper.rb +46 -42
  59. data/lib/pry/commands/ls/self_methods.rb +23 -22
  60. data/lib/pry/commands/ls.rb +124 -102
  61. data/lib/pry/commands/nesting.rb +21 -17
  62. data/lib/pry/commands/play.rb +93 -82
  63. data/lib/pry/commands/pry_backtrace.rb +22 -17
  64. data/lib/pry/commands/pry_version.rb +15 -11
  65. data/lib/pry/commands/raise_up.rb +27 -22
  66. data/lib/pry/commands/reload_code.rb +60 -48
  67. data/lib/pry/commands/reset.rb +16 -12
  68. data/lib/pry/commands/ri.rb +55 -45
  69. data/lib/pry/commands/save_file.rb +45 -43
  70. data/lib/pry/commands/shell_command.rb +51 -51
  71. data/lib/pry/commands/shell_mode.rb +21 -17
  72. data/lib/pry/commands/show_doc.rb +80 -68
  73. data/lib/pry/commands/show_info.rb +189 -171
  74. data/lib/pry/commands/show_input.rb +16 -11
  75. data/lib/pry/commands/show_source.rb +110 -45
  76. data/lib/pry/commands/stat.rb +35 -31
  77. data/lib/pry/commands/switch_to.rb +21 -15
  78. data/lib/pry/commands/toggle_color.rb +20 -16
  79. data/lib/pry/commands/watch_expression/expression.rb +32 -27
  80. data/lib/pry/commands/watch_expression.rb +89 -86
  81. data/lib/pry/commands/whereami.rb +156 -148
  82. data/lib/pry/commands/wtf.rb +75 -50
  83. data/lib/pry/config/attributable.rb +22 -0
  84. data/lib/pry/config/lazy_value.rb +29 -0
  85. data/lib/pry/config/memoized_value.rb +34 -0
  86. data/lib/pry/config/value.rb +24 -0
  87. data/lib/pry/config.rb +307 -25
  88. data/lib/pry/control_d_handler.rb +28 -0
  89. data/lib/pry/core_extensions.rb +9 -7
  90. data/lib/pry/editor.rb +48 -21
  91. data/lib/pry/env.rb +18 -0
  92. data/lib/pry/exception_handler.rb +43 -0
  93. data/lib/pry/exceptions.rb +13 -16
  94. data/lib/pry/forwardable.rb +5 -1
  95. data/lib/pry/helpers/base_helpers.rb +68 -197
  96. data/lib/pry/helpers/command_helpers.rb +50 -61
  97. data/lib/pry/helpers/documentation_helpers.rb +21 -13
  98. data/lib/pry/helpers/options_helpers.rb +14 -7
  99. data/lib/pry/helpers/platform.rb +7 -5
  100. data/lib/pry/helpers/table.rb +33 -26
  101. data/lib/pry/helpers/text.rb +22 -19
  102. data/lib/pry/helpers.rb +2 -0
  103. data/lib/pry/history.rb +48 -56
  104. data/lib/pry/hooks.rb +21 -12
  105. data/lib/pry/indent.rb +54 -50
  106. data/lib/pry/input_completer.rb +248 -230
  107. data/lib/pry/input_lock.rb +8 -9
  108. data/lib/pry/inspector.rb +36 -24
  109. data/lib/pry/last_exception.rb +45 -45
  110. data/lib/pry/method/disowned.rb +16 -4
  111. data/lib/pry/method/patcher.rb +12 -3
  112. data/lib/pry/method/weird_method_locator.rb +68 -44
  113. data/lib/pry/method.rb +141 -94
  114. data/lib/pry/object_path.rb +33 -25
  115. data/lib/pry/output.rb +121 -35
  116. data/lib/pry/pager.rb +41 -42
  117. data/lib/pry/prompt.rb +123 -54
  118. data/lib/pry/pry_class.rb +61 -103
  119. data/lib/pry/pry_instance.rb +217 -215
  120. data/lib/pry/repl.rb +18 -22
  121. data/lib/pry/repl_file_loader.rb +27 -21
  122. data/lib/pry/ring.rb +11 -6
  123. data/lib/pry/slop/commands.rb +164 -169
  124. data/lib/pry/slop/option.rb +172 -168
  125. data/lib/pry/slop.rb +574 -563
  126. data/lib/pry/syntax_highlighter.rb +26 -0
  127. data/lib/pry/system_command_handler.rb +17 -0
  128. data/lib/pry/testable/evalable.rb +21 -12
  129. data/lib/pry/testable/mockable.rb +18 -10
  130. data/lib/pry/testable/pry_tester.rb +71 -56
  131. data/lib/pry/testable/utility.rb +29 -21
  132. data/lib/pry/testable/variables.rb +49 -43
  133. data/lib/pry/testable.rb +59 -61
  134. data/lib/pry/version.rb +3 -1
  135. data/lib/pry/warning.rb +27 -0
  136. data/lib/pry/wrapped_module/candidate.rb +21 -14
  137. data/lib/pry/wrapped_module.rb +51 -42
  138. data/lib/pry.rb +132 -119
  139. metadata +34 -34
  140. data/lib/pry/commands/disabled_commands.rb +0 -2
  141. data/lib/pry/commands/gem_cd.rb +0 -26
  142. data/lib/pry/commands/gem_install.rb +0 -32
  143. data/lib/pry/commands/gem_list.rb +0 -33
  144. data/lib/pry/commands/gem_open.rb +0 -29
  145. data/lib/pry/commands/gem_readme.rb +0 -25
  146. data/lib/pry/commands/gem_search.rb +0 -40
  147. data/lib/pry/commands/gem_stats.rb +0 -83
  148. data/lib/pry/commands/gist.rb +0 -102
  149. data/lib/pry/commands/install_command.rb +0 -54
  150. data/lib/pry/commands.rb +0 -6
  151. data/lib/pry/config/behavior.rb +0 -255
  152. data/lib/pry/config/convenience.rb +0 -28
  153. data/lib/pry/config/default.rb +0 -159
  154. data/lib/pry/config/memoization.rb +0 -48
  155. data/lib/pry/platform.rb +0 -91
  156. data/lib/pry/plugins.rb +0 -122
  157. data/lib/pry/rubygem.rb +0 -84
  158. data/lib/pry/terminal.rb +0 -91
@@ -1,32 +0,0 @@
1
- class Pry
2
- class Command::GemInstall < Pry::ClassCommand
3
- match 'gem-install'
4
- group 'Gems'
5
- description 'Install a gem and refresh the gem cache.'
6
- command_options argument_required: true
7
-
8
- banner <<-'BANNER'
9
- Usage: gem-install GEM_NAME
10
-
11
- Installs the given gem, refreshes the gem cache, and requires the gem for you
12
- based on a best guess from the gem name.
13
-
14
- gem-install pry-stack_explorer
15
- BANNER
16
-
17
- def setup
18
- require 'rubygems/dependency_installer' unless defined? Gem::DependencyInstaller
19
- end
20
-
21
- def process(gem)
22
- Rubygem.install(gem)
23
- output.puts "Gem `#{ green(gem) }` installed."
24
- require gem
25
- rescue LoadError
26
- require_path = gem.split('-').join('/')
27
- require require_path
28
- end
29
- end
30
-
31
- Pry::Commands.add_command(Pry::Command::GemInstall)
32
- end
@@ -1,33 +0,0 @@
1
- class Pry
2
- class Command::GemList < Pry::ClassCommand
3
- match 'gem-list'
4
- group 'Gems'
5
- description 'List and search installed gems.'
6
-
7
- banner <<-'BANNER'
8
- Usage: gem-list [REGEX]
9
-
10
- List all installed gems, when a regex is provided, limit the output to those
11
- that match the regex.
12
- BANNER
13
-
14
- def process(pattern = nil)
15
- pattern = Regexp.compile(pattern || '')
16
- gems = Rubygem.list(pattern).group_by(&:name)
17
-
18
- gems.each do |gem, specs|
19
- specs.sort! do |a,b|
20
- Gem::Version.new(b.version) <=> Gem::Version.new(a.version)
21
- end
22
-
23
- versions = specs.each_with_index.map do |spec, index|
24
- index == 0 ? bright_green(spec.version.to_s) : green(spec.version.to_s)
25
- end
26
-
27
- output.puts "#{default gem} (#{versions.join ', '})"
28
- end
29
- end
30
- end
31
-
32
- Pry::Commands.add_command(Pry::Command::GemList)
33
- end
@@ -1,29 +0,0 @@
1
- class Pry
2
- class Command::GemOpen < Pry::ClassCommand
3
- match 'gem-open'
4
- group 'Gems'
5
- description 'Opens the working directory of the gem in your editor.'
6
- command_options argument_required: true
7
-
8
- banner <<-'BANNER'
9
- Usage: gem-open GEM_NAME
10
-
11
- Change the current working directory to that in which the given gem is
12
- installed, and then opens your text editor.
13
-
14
- gem-open pry-exception_explorer
15
- BANNER
16
-
17
- def process(gem)
18
- Dir.chdir(Rubygem.spec(gem).full_gem_path) do
19
- Pry::Editor.new(_pry_).invoke_editor(".", 0, false)
20
- end
21
- end
22
-
23
- def complete(str)
24
- Rubygem.complete(str)
25
- end
26
- end
27
-
28
- Pry::Commands.add_command(Pry::Command::GemOpen)
29
- end
@@ -1,25 +0,0 @@
1
- class Pry::Command::GemReadme < Pry::ClassCommand
2
- match 'gem-readme'
3
- description 'Show the readme bundled with a rubygem'
4
- group 'Gems'
5
- command_options argument_required: true
6
- banner <<-BANNER
7
- gem-readme gem
8
- Show the readme bundled with a rubygem
9
- BANNER
10
-
11
- def process(name)
12
- spec = Gem::Specification.find_by_name(name)
13
- glob = File.join(spec.full_gem_path, 'README*')
14
- readme = Dir[glob][0]
15
- if File.exist?(readme.to_s)
16
- _pry_.pager.page File.read(readme)
17
- else
18
- raise Pry::CommandError, "Gem '#{name}' doesn't appear to have a README"
19
- end
20
- rescue Gem::LoadError
21
- raise Pry::CommandError, "Gem '#{name}' wasn't found. Are you sure it is installed?"
22
- end
23
-
24
- Pry::Commands.add_command(self)
25
- end
@@ -1,40 +0,0 @@
1
- class Pry::Command::GemSearch < Pry::ClassCommand
2
- match 'gem-search'
3
- description 'Search for a gem with the rubygems.org JSON API'
4
- group 'Gems'
5
- command_options argument_required: true
6
- banner <<-BANNER
7
- gem-search [options] gem
8
- Search for a gem with the rubygems.org HTTP API
9
- BANNER
10
-
11
- API_ENDPOINT = 'https://rubygems.org/api/v1/search.json'
12
-
13
- def setup
14
- require 'json' unless defined?(JSON)
15
- require 'net/http' unless defined?(Net::HTTP)
16
- end
17
-
18
- def options(opt)
19
- opt.on :l, :limit, 'Limit the number of results (max: 30)',
20
- default: 10,
21
- as: Integer,
22
- argument: true
23
- end
24
-
25
- def process(str)
26
- uri = URI.parse(API_ENDPOINT)
27
- uri.query = URI.encode_www_form(query: str)
28
- gems = JSON.load Net::HTTP.get(uri)
29
- _pry_.pager.page list_as_string(gems, opts[:limit])
30
- end
31
-
32
- private
33
- def list_as_string(gems, limit = 10)
34
- gems[0..limit - 1].map do |gem|
35
- name, version, info = gem.values_at 'name', 'version', 'info'
36
- "#{bold(name)} #{bold('v' + version)} \n#{info}\n\n"
37
- end.join
38
- end
39
- Pry::Commands.add_command(self)
40
- end
@@ -1,83 +0,0 @@
1
- class Pry::Command::GemStat < Pry::ClassCommand
2
- require 'json'
3
- require 'net/http'
4
- STAT_HOST = "rubygems.org"
5
- STAT_PORT = 443
6
- STAT_PATH = "/api/v1/gems/%s.json"
7
- FAIL_WHALE = <<-FAILWHALE
8
- W W W
9
- W W W W
10
- '. W
11
- .-""-._ \ \.--|
12
- / "-..__) .-'
13
- | _ /
14
- \'-.__, .__.,'
15
- `'----'._\--'
16
- VVVVVVVVVVVVVVVVVVVVV
17
- FAILWHALE
18
-
19
- match 'gem-stat'
20
- description 'Show the statistics of a gem (requires internet connection)'
21
- group 'Gems'
22
- command_options argument_required: true
23
- banner <<-BANNER
24
- gem-stats name
25
-
26
- Show the statistics of a gem.
27
- Requires an internet connection.
28
- BANNER
29
-
30
- def process(name)
31
- client = Net::HTTP.start STAT_HOST, STAT_PORT, use_ssl: true
32
- res = client.get STAT_PATH % URI.encode_www_form_component(name)
33
- case res
34
- when Net::HTTPOK
35
- _pry_.pager.page format_gem(JSON.parse(res.body))
36
- when Net::HTTPServiceUnavailable
37
- _pry_.pager.page <<-FAILURE
38
- #{bright_blue(FAIL_WHALE)}
39
- #{bright_red('Ruby On Rails')}
40
- #{bright_red('Net::HTTPServiceUnavailable')}
41
- FAILURE
42
- else
43
- raise Pry::CommandError, "Bad response (#{res.class})"
44
- end
45
- ensure
46
- client.finish if client
47
- end
48
-
49
- private
50
- def format_gem(h)
51
- h = Pry::Config.from_hash(h, nil)
52
- format_str = unindent <<-FORMAT
53
- %{name} %{version}
54
- --
55
- Total Downloads : %{downloads}
56
- Version Downloads : %{version_downloads}
57
-
58
- #{red('Dependencies')} (runtime)
59
- --
60
- %{rdependencies}
61
-
62
- #{red('Dependencies')} (development)
63
- %{ddependencies}
64
- FORMAT
65
- format_str % {name: green(h.name),
66
- version: bold("v#{h.version}"),
67
- downloads: h.downloads,
68
- version_downloads: h.version_downloads,
69
- rdependencies: format_dependencies(h.dependencies.runtime),
70
- ddependencies: format_dependencies(h.dependencies.development)}
71
- end
72
-
73
- def format_dependencies(rdeps)
74
- return bold('None') if rdeps.empty?
75
-
76
- with_line_numbers(
77
- rdeps.map { |h| "#{h['name']} (#{h['requirements']})" }.join("\n"),
78
- 1,
79
- :bold
80
- )
81
- end
82
- Pry::Commands.add_command(self)
83
- end
@@ -1,102 +0,0 @@
1
- class Pry
2
- class Command::Gist < Pry::ClassCommand
3
- match 'gist'
4
- group 'Misc'
5
- description 'Upload code, docs, history to https://gist.github.com/.'
6
- command_options requires_gem: "gist"
7
-
8
- banner <<-'BANNER'
9
- Usage: gist [OPTIONS] [--help]
10
-
11
- The gist command enables you to gist code from files and methods to github.
12
-
13
- gist -i 20 --lines 1..3
14
- gist Pry#repl --lines 1..-1
15
- gist Rakefile --lines 5
16
- BANNER
17
-
18
- def setup
19
- require 'gist'
20
- end
21
-
22
- def options(opt)
23
- CodeCollector.inject_options(opt)
24
- opt.on :login, "Authenticate the gist gem with GitHub"
25
- opt.on :p, :public, "Create a public gist (default: false)", default: false
26
- opt.on :clip, "Copy the selected content to clipboard instead, do NOT gist it", default: false
27
- end
28
-
29
- def process
30
- return ::Gist.login! if opts.present?(:login)
31
-
32
- cc = CodeCollector.new(args, opts, _pry_)
33
-
34
- if cc.content =~ /\A\s*\z/
35
- raise CommandError, "Found no code to gist."
36
- end
37
-
38
- if opts.present?(:clip)
39
- clipboard_content(cc.content)
40
- else
41
- # we're overriding the default behavior of the 'in' option (as
42
- # defined on CodeCollector) with our local behaviour.
43
- content = opts.present?(:in) ? input_content : cc.content
44
- gist_content content, cc.file
45
- end
46
- end
47
-
48
- def clipboard_content(content)
49
- ::Gist.copy(content)
50
- output.puts "Copied content to clipboard!"
51
- end
52
-
53
- def input_content
54
- content = ""
55
- CodeCollector.input_expression_ranges.each do |range|
56
- input_expressions = _pry_.input_ring[range] || []
57
- Array(input_expressions).each_with_index do |code, index|
58
- corrected_index = index + range.first
59
- if code && code != ""
60
- content << code
61
- if code !~ /;\Z/
62
- content << "#{comment_expression_result_for_gist(_pry_.config.gist.inspecter.call(_pry_.output_ring[corrected_index]))}"
63
- end
64
- end
65
- end
66
- end
67
-
68
- content
69
- end
70
-
71
- def comment_expression_result_for_gist(result)
72
- content = ""
73
- result.lines.each_with_index do |line, index|
74
- if index == 0
75
- content << "# => #{line}"
76
- else
77
- content << "# #{line}"
78
- end
79
- end
80
-
81
- content
82
- end
83
-
84
- def gist_content(content, filename)
85
- response = ::Gist.gist(content, filename: filename || "pry_gist.rb", public: !!opts[:p])
86
- if response
87
- url = response['html_url']
88
- message = "Gist created at URL #{url}"
89
- begin
90
- ::Gist.copy(url)
91
- message << ", which is now in the clipboard."
92
- rescue ::Gist::ClipboardError
93
- end
94
-
95
- output.puts message
96
- end
97
- end
98
- end
99
-
100
- Pry::Commands.add_command(Pry::Command::Gist)
101
- Pry::Commands.alias_command 'clipit', 'gist --clip'
102
- end
@@ -1,54 +0,0 @@
1
- class Pry
2
- class Command::InstallCommand < Pry::ClassCommand
3
- match 'install-command'
4
- group 'Commands'
5
- description 'Install a disabled command.'
6
-
7
- banner <<-'BANNER'
8
- Usage: install-command COMMAND
9
-
10
- Installs the gems necessary to run the given COMMAND. You will generally not
11
- need to run this unless told to by an error message.
12
- BANNER
13
-
14
- def process(name)
15
- require 'rubygems/dependency_installer' unless defined? Gem::DependencyInstaller
16
- command = find_command(name)
17
-
18
- unless command
19
- output.puts "Command #{ green(name) } is not found"
20
- return
21
- end
22
-
23
- if command_dependencies_met?(command.options)
24
- output.puts "Dependencies for #{ green(name) } are met. Nothing to do"
25
- return
26
- end
27
-
28
- output.puts "Attempting to install #{ green(name) } command..."
29
- gems_to_install = Array(command.options[:requires_gem])
30
-
31
- gems_to_install.each do |g|
32
- next if Rubygem.installed?(g)
33
-
34
- output.puts "Installing #{ green(g) } gem..."
35
- Rubygem.install(g)
36
- end
37
-
38
- gems_to_install.each do |g|
39
- begin
40
- require g
41
- rescue LoadError
42
- fail_msg = "Required gem #{ green(g) } installed but not found."
43
- fail_msg += " Aborting command installation\n"
44
- fail_msg += 'Tips: 1. Check your PATH; 2. Run `bundle update`'
45
- raise CommandError, fail_msg
46
- end
47
- end
48
-
49
- output.puts "Installation of #{ green(name) } successful! Type `help #{name}` for information"
50
- end
51
- end
52
-
53
- Pry::Commands.add_command(Pry::Command::InstallCommand)
54
- end
data/lib/pry/commands.rb DELETED
@@ -1,6 +0,0 @@
1
- # Default commands used by Pry.
2
- Pry::Commands = Pry::CommandSet.new
3
-
4
- Dir[File.expand_path('../commands', __FILE__) << '/*.rb'].each do |file|
5
- require file
6
- end
@@ -1,255 +0,0 @@
1
- class Pry
2
- class Config < Pry::BasicObject
3
- module Behavior
4
- ASSIGNMENT = "=".freeze
5
- NODUP = [TrueClass, FalseClass, NilClass, Symbol, Numeric, Module, Proc].freeze
6
- INSPECT_REGEXP = /#{Regexp.escape "default=#<"}/
7
- ReservedKeyError = Class.new(RuntimeError)
8
-
9
- module Builder
10
- #
11
- # Returns a new Behavior, non-recursively (unlike {#from_hash}).
12
- #
13
- # @param
14
- # (see #from_hash)
15
- #
16
- # @return
17
- # (see #from_hash)
18
- #
19
- def assign(attributes, default = nil)
20
- new(default).tap do |behavior|
21
- behavior.merge!(attributes)
22
- end
23
- end
24
-
25
- #
26
- # Returns a new Behavior, recursively walking attributes.
27
- #
28
- # @param [Hash] attributes
29
- # a hash to initialize an instance of self with.
30
- #
31
- # @param [Pry::Config, nil] default
32
- # a default, or nil for none.
33
- #
34
- # @return [Pry::Config]
35
- # returns an instance of self.
36
- #
37
- def from_hash(attributes, default = nil)
38
- new(default).tap do |config|
39
- attributes.each do |key,value|
40
- config[key] = Hash === value ? from_hash(value, nil) : value
41
- end
42
- end
43
- end
44
- end
45
-
46
- def self.included(klass)
47
- klass.extend(Builder)
48
- end
49
-
50
- def initialize(default = Pry.config)
51
- @default = default
52
- @lookup = {}
53
- @reserved_keys = methods.map(&:to_s).freeze
54
- end
55
-
56
- #
57
- # @return [Pry::Config::Behavior]
58
- # returns the default used incase a key isn't found in self.
59
- #
60
- def default
61
- @default
62
- end
63
-
64
- #
65
- # @param [String] key
66
- # a key (as a String)
67
- #
68
- # @return [Object, BasicObject]
69
- # returns an object from self or one of its defaults.
70
- #
71
- def [](key)
72
- key = key.to_s
73
- key?(key) ? @lookup[key] : (@default and @default[key])
74
- end
75
-
76
- #
77
- # Add a key and value pair to self.
78
- #
79
- # @param [String] key
80
- # a key (as a String).
81
- #
82
- # @param [Object,BasicObject] value
83
- # a value.
84
- #
85
- # @raise [Pry::Config::ReservedKeyError]
86
- # when 'key' is a reserved key name.
87
- #
88
- def []=(key, value)
89
- key = key.to_s
90
- if @reserved_keys.include?(key)
91
- raise ReservedKeyError, "It is not possible to use '#{key}' as a key name, please choose a different key name."
92
- end
93
-
94
- __push(key,value)
95
- end
96
-
97
- #
98
- # Removes a key from self.
99
- #
100
- # @param [String] key
101
- # a key (as a String)
102
- #
103
- # @return [void]
104
- #
105
- def forget(key)
106
- key = key.to_s
107
- __remove(key)
108
- end
109
-
110
- #
111
- # @param [Hash, #to_h, #to_hash] other
112
- # a hash to merge into self.
113
- #
114
- # @return [void]
115
- #
116
- def merge!(other)
117
- other = __try_convert_to_hash(other)
118
- raise TypeError, "unable to convert argument into a Hash" unless other
119
-
120
- other.each do |key, value|
121
- self[key] = value
122
- end
123
- end
124
-
125
- #
126
- # @param [Hash, #to_h, #to_hash] other
127
- # a hash to compare against the lookup table of self.
128
- #
129
- def ==(other)
130
- @lookup == __try_convert_to_hash(other)
131
- end
132
- alias_method :eql?, :==
133
-
134
- #
135
- # @param [String] key
136
- # a key (as a String)
137
- #
138
- # @return [Boolean]
139
- # returns true when "key" is a member of self.
140
- #
141
- def key?(key)
142
- key = key.to_s
143
- @lookup.key?(key)
144
- end
145
-
146
- #
147
- # Clear the lookup table of self.
148
- #
149
- # @return [void]
150
- #
151
- def clear
152
- @lookup.clear
153
- true
154
- end
155
-
156
- #
157
- # @return [Array<String>]
158
- # returns an array of keys in self.
159
- #
160
- def keys
161
- @lookup.keys
162
- end
163
-
164
- def eager_load!
165
- default = @default
166
- while default
167
- default.memoized_methods.each { |method| self[key] = default.public_send(key) } if default.respond_to?(:memoized_methods)
168
- default = @default.default
169
- end
170
- end
171
-
172
- def last_default
173
- last = @default
174
- last = last.default while last and last.default
175
- last
176
- end
177
-
178
- #
179
- # @return [Hash]
180
- # returns a duplicate copy of the lookup table used by self.
181
- #
182
- def to_hash
183
- @lookup.dup
184
- end
185
- alias_method :to_h, :to_hash
186
-
187
- def inspect
188
- key_str = keys.map { |key| "'#{key}'" }.join(",")
189
- "#<#{__clip_inspect(self)} keys=[#{key_str}] default=#{@default.inspect}>"
190
- end
191
-
192
- def pretty_print(q)
193
- q.text inspect[1..-1].gsub(INSPECT_REGEXP, "default=<")
194
- end
195
-
196
- def method_missing(name, *args, &block)
197
- key = name.to_s
198
- if key[-1] == ASSIGNMENT
199
- short_key = key[0..-2]
200
- self[short_key] = args[0]
201
- elsif key?(key)
202
- self[key]
203
- elsif @default.respond_to?(name)
204
- value = @default.public_send(name, *args, &block)
205
- self[key] = __dup(value)
206
- else
207
- nil
208
- end
209
- end
210
-
211
- def respond_to_missing?(key, include_all = false)
212
- key = key.to_s.chomp(ASSIGNMENT)
213
- key?(key) or @default.respond_to?(key) or super(key, include_all)
214
- end
215
-
216
- private
217
-
218
- def __clip_inspect(obj)
219
- "#{obj.class}:0x%x" % obj.object_id
220
- end
221
-
222
- def __try_convert_to_hash(obj)
223
- if Hash === obj
224
- obj
225
- elsif obj.respond_to?(:to_h)
226
- obj.to_h
227
- elsif obj.respond_to?(:to_hash)
228
- obj.to_hash
229
- else
230
- nil
231
- end
232
- end
233
-
234
- def __dup(value)
235
- if NODUP.any? { |klass| klass === value }
236
- value
237
- else
238
- value.dup
239
- end
240
- end
241
-
242
- def __push(key,value)
243
- unless singleton_class.method_defined? key
244
- define_singleton_method(key) { self[key] }
245
- define_singleton_method("#{key}=") { |val| @lookup[key] = val }
246
- end
247
- @lookup[key] = value
248
- end
249
-
250
- def __remove(key)
251
- @lookup.delete(key)
252
- end
253
- end
254
- end
255
- end
@@ -1,28 +0,0 @@
1
- class Pry
2
- class Config < Pry::BasicObject
3
- module Convenience
4
- SHORTCUTS = [
5
- :input,
6
- :output,
7
- :commands,
8
- :print,
9
- :exception_handler,
10
- :hooks,
11
- :color,
12
- :pager,
13
- :editor,
14
- :memory_size,
15
- :extra_sticky_locals
16
- ]
17
-
18
- def config_shortcut(*names)
19
- names.each do |name|
20
- reader = name
21
- setter = "#{name}="
22
- define_method(reader) { config.public_send(name) }
23
- define_method(setter) { |value| config.public_send(setter, value) }
24
- end
25
- end
26
- end
27
- end
28
- end