rubygems-update 3.3.26 → 3.4.1

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 (272) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +35 -0
  3. data/CONTRIBUTING.md +24 -1
  4. data/Manifest.txt +30 -27
  5. data/POLICIES.md +10 -8
  6. data/README.md +2 -2
  7. data/bin/gem +1 -4
  8. data/bin/update_rubygems +1 -1
  9. data/bundler/CHANGELOG.md +59 -0
  10. data/bundler/README.md +2 -2
  11. data/bundler/bundler.gemspec +2 -2
  12. data/bundler/exe/bundle +1 -4
  13. data/bundler/lib/bundler/build_metadata.rb +2 -2
  14. data/bundler/lib/bundler/cli/add.rb +1 -1
  15. data/bundler/lib/bundler/cli/check.rb +1 -1
  16. data/bundler/lib/bundler/cli/common.rb +1 -0
  17. data/bundler/lib/bundler/cli/console.rb +2 -2
  18. data/bundler/lib/bundler/cli/doctor.rb +4 -6
  19. data/bundler/lib/bundler/cli/gem.rb +62 -40
  20. data/bundler/lib/bundler/cli/install.rb +2 -3
  21. data/bundler/lib/bundler/cli/lock.rb +8 -5
  22. data/bundler/lib/bundler/cli/outdated.rb +1 -3
  23. data/bundler/lib/bundler/cli/viz.rb +1 -1
  24. data/bundler/lib/bundler/cli.rb +43 -2
  25. data/bundler/lib/bundler/compact_index_client/cache.rb +1 -1
  26. data/bundler/lib/bundler/compact_index_client/updater.rb +40 -39
  27. data/bundler/lib/bundler/constants.rb +1 -1
  28. data/bundler/lib/bundler/definition.rb +61 -31
  29. data/bundler/lib/bundler/dependency.rb +12 -11
  30. data/bundler/lib/bundler/digest.rb +1 -1
  31. data/bundler/lib/bundler/dsl.rb +1 -1
  32. data/bundler/lib/bundler/env.rb +1 -1
  33. data/bundler/lib/bundler/environment_preserver.rb +1 -0
  34. data/bundler/lib/bundler/errors.rb +1 -11
  35. data/bundler/lib/bundler/fetcher/compact_index.rb +9 -11
  36. data/bundler/lib/bundler/fetcher/dependency.rb +1 -1
  37. data/bundler/lib/bundler/fetcher/downloader.rb +2 -5
  38. data/bundler/lib/bundler/fetcher.rb +2 -6
  39. data/bundler/lib/bundler/force_platform.rb +18 -0
  40. data/bundler/lib/bundler/friendly_errors.rb +0 -3
  41. data/bundler/lib/bundler/gem_version_promoter.rb +52 -86
  42. data/bundler/lib/bundler/graph.rb +3 -3
  43. data/bundler/lib/bundler/index.rb +5 -13
  44. data/bundler/lib/bundler/injector.rb +1 -1
  45. data/bundler/lib/bundler/inline.rb +2 -2
  46. data/bundler/lib/bundler/installer/parallel_installer.rb +0 -31
  47. data/bundler/lib/bundler/installer.rb +6 -16
  48. data/bundler/lib/bundler/lazy_specification.rb +5 -1
  49. data/bundler/lib/bundler/lockfile_parser.rb +5 -5
  50. data/bundler/lib/bundler/man/bundle-add.1 +1 -1
  51. data/bundler/lib/bundler/man/bundle-binstubs.1 +1 -1
  52. data/bundler/lib/bundler/man/bundle-cache.1 +1 -1
  53. data/bundler/lib/bundler/man/bundle-check.1 +1 -1
  54. data/bundler/lib/bundler/man/bundle-clean.1 +1 -1
  55. data/bundler/lib/bundler/man/bundle-config.1 +1 -1
  56. data/bundler/lib/bundler/man/bundle-console.1 +1 -1
  57. data/bundler/lib/bundler/man/bundle-doctor.1 +1 -1
  58. data/bundler/lib/bundler/man/bundle-exec.1 +1 -1
  59. data/bundler/lib/bundler/man/bundle-gem.1 +27 -37
  60. data/bundler/lib/bundler/man/bundle-gem.1.ronn +5 -5
  61. data/bundler/lib/bundler/man/bundle-help.1 +1 -1
  62. data/bundler/lib/bundler/man/bundle-info.1 +1 -1
  63. data/bundler/lib/bundler/man/bundle-init.1 +1 -1
  64. data/bundler/lib/bundler/man/bundle-inject.1 +1 -1
  65. data/bundler/lib/bundler/man/bundle-install.1 +1 -30
  66. data/bundler/lib/bundler/man/bundle-install.1.ronn +0 -29
  67. data/bundler/lib/bundler/man/bundle-list.1 +1 -1
  68. data/bundler/lib/bundler/man/bundle-lock.1 +1 -1
  69. data/bundler/lib/bundler/man/bundle-open.1 +1 -1
  70. data/bundler/lib/bundler/man/bundle-outdated.1 +1 -1
  71. data/bundler/lib/bundler/man/bundle-platform.1 +2 -2
  72. data/bundler/lib/bundler/man/bundle-platform.1.ronn +1 -1
  73. data/bundler/lib/bundler/man/bundle-plugin.1 +1 -1
  74. data/bundler/lib/bundler/man/bundle-pristine.1 +1 -1
  75. data/bundler/lib/bundler/man/bundle-remove.1 +1 -1
  76. data/bundler/lib/bundler/man/bundle-show.1 +1 -1
  77. data/bundler/lib/bundler/man/bundle-update.1 +1 -1
  78. data/bundler/lib/bundler/man/bundle-version.1 +1 -1
  79. data/bundler/lib/bundler/man/bundle-viz.1 +1 -1
  80. data/bundler/lib/bundler/man/bundle.1 +1 -1
  81. data/bundler/lib/bundler/man/gemfile.5 +1 -1
  82. data/bundler/lib/bundler/mirror.rb +5 -7
  83. data/bundler/lib/bundler/plugin/index.rb +4 -4
  84. data/bundler/lib/bundler/plugin/installer/rubygems.rb +0 -4
  85. data/bundler/lib/bundler/resolver/base.rb +7 -11
  86. data/bundler/lib/bundler/resolver/candidate.rb +92 -0
  87. data/bundler/lib/bundler/resolver/incompatibility.rb +15 -0
  88. data/bundler/lib/bundler/resolver/package.rb +63 -0
  89. data/bundler/lib/bundler/resolver/root.rb +25 -0
  90. data/bundler/lib/bundler/resolver/spec_group.rb +26 -36
  91. data/bundler/lib/bundler/resolver.rb +294 -277
  92. data/bundler/lib/bundler/rubygems_ext.rb +11 -6
  93. data/bundler/lib/bundler/rubygems_gem_installer.rb +4 -2
  94. data/bundler/lib/bundler/rubygems_integration.rb +1 -9
  95. data/bundler/lib/bundler/runtime.rb +1 -5
  96. data/bundler/lib/bundler/settings.rb +0 -6
  97. data/bundler/lib/bundler/shared_helpers.rb +1 -0
  98. data/bundler/lib/bundler/source/git/git_proxy.rb +193 -67
  99. data/bundler/lib/bundler/source/git.rb +15 -17
  100. data/bundler/lib/bundler/source/metadata.rb +0 -1
  101. data/bundler/lib/bundler/source/path/installer.rb +1 -22
  102. data/bundler/lib/bundler/source/path.rb +5 -5
  103. data/bundler/lib/bundler/source/rubygems.rb +13 -67
  104. data/bundler/lib/bundler/source_list.rb +8 -2
  105. data/bundler/lib/bundler/spec_set.rb +7 -9
  106. data/bundler/lib/bundler/templates/Executable +1 -1
  107. data/bundler/lib/bundler/templates/Executable.bundler +4 -9
  108. data/bundler/lib/bundler/templates/Executable.standalone +2 -0
  109. data/bundler/lib/bundler/templates/newgem/Cargo.toml.tt +7 -0
  110. data/bundler/lib/bundler/templates/newgem/Gemfile.tt +3 -0
  111. data/bundler/lib/bundler/templates/newgem/README.md.tt +6 -4
  112. data/bundler/lib/bundler/templates/newgem/Rakefile.tt +2 -1
  113. data/bundler/lib/bundler/templates/newgem/circleci/config.yml.tt +12 -0
  114. data/bundler/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +15 -0
  115. data/bundler/lib/bundler/templates/newgem/ext/newgem/{extconf.rb.tt → extconf-c.rb.tt} +0 -0
  116. data/bundler/lib/bundler/templates/newgem/ext/newgem/extconf-rust.rb.tt +6 -0
  117. data/bundler/lib/bundler/templates/newgem/ext/newgem/src/lib.rs.tt +12 -0
  118. data/bundler/lib/bundler/templates/newgem/github/workflows/main.yml.tt +10 -0
  119. data/bundler/lib/bundler/templates/newgem/gitignore.tt +3 -0
  120. data/bundler/lib/bundler/templates/newgem/gitlab-ci.yml.tt +8 -0
  121. data/bundler/lib/bundler/templates/newgem/newgem.gemspec.tt +8 -2
  122. data/bundler/lib/bundler/ui/shell.rb +35 -12
  123. data/bundler/lib/bundler/ui/silent.rb +21 -5
  124. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +3 -3
  125. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +0 -1
  126. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +3 -1
  127. data/bundler/lib/bundler/vendor/fileutils/lib/fileutils.rb +1350 -408
  128. data/bundler/lib/bundler/vendor/net-http-persistent/README.rdoc +1 -1
  129. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +1 -1
  130. data/bundler/lib/bundler/vendor/pub_grub/LICENSE.txt +21 -0
  131. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/assignment.rb +20 -0
  132. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +189 -0
  133. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/failure_writer.rb +182 -0
  134. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/incompatibility.rb +151 -0
  135. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/package.rb +43 -0
  136. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/partial_solution.rb +121 -0
  137. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/rubygems.rb +45 -0
  138. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/solve_failure.rb +19 -0
  139. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb +53 -0
  140. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/term.rb +105 -0
  141. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version.rb +3 -0
  142. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_constraint.rb +124 -0
  143. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb +409 -0
  144. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb +240 -0
  145. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_union.rb +178 -0
  146. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub.rb +31 -0
  147. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +1 -1
  148. data/bundler/lib/bundler/vendor/uri/lib/uri/common.rb +64 -16
  149. data/bundler/lib/bundler/vendor/uri/lib/uri/file.rb +7 -1
  150. data/bundler/lib/bundler/vendor/uri/lib/uri/ftp.rb +2 -1
  151. data/bundler/lib/bundler/vendor/uri/lib/uri/generic.rb +27 -7
  152. data/bundler/lib/bundler/vendor/uri/lib/uri/http.rb +40 -2
  153. data/bundler/lib/bundler/vendor/uri/lib/uri/https.rb +2 -1
  154. data/bundler/lib/bundler/vendor/uri/lib/uri/ldap.rb +1 -1
  155. data/bundler/lib/bundler/vendor/uri/lib/uri/ldaps.rb +2 -1
  156. data/bundler/lib/bundler/vendor/uri/lib/uri/mailto.rb +2 -2
  157. data/bundler/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +13 -7
  158. data/bundler/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +10 -5
  159. data/bundler/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
  160. data/bundler/lib/bundler/vendor/uri/lib/uri/ws.rb +1 -2
  161. data/bundler/lib/bundler/vendor/uri/lib/uri/wss.rb +2 -1
  162. data/bundler/lib/bundler/vendor/uri/lib/uri.rb +3 -2
  163. data/bundler/lib/bundler/vendored_persistent.rb +1 -33
  164. data/bundler/lib/bundler/{vendored_tmpdir.rb → vendored_pub_grub.rb} +1 -1
  165. data/bundler/lib/bundler/version.rb +5 -1
  166. data/bundler/lib/bundler/worker.rb +5 -7
  167. data/bundler/lib/bundler.rb +20 -64
  168. data/lib/rubygems/command_manager.rb +2 -2
  169. data/lib/rubygems/commands/fetch_command.rb +1 -1
  170. data/lib/rubygems/commands/install_command.rb +7 -3
  171. data/lib/rubygems/commands/rdoc_command.rb +3 -2
  172. data/lib/rubygems/commands/setup_command.rb +2 -2
  173. data/lib/rubygems/commands/unpack_command.rb +1 -1
  174. data/lib/rubygems/commands/update_command.rb +1 -7
  175. data/lib/rubygems/config_file.rb +33 -0
  176. data/lib/rubygems/core_ext/kernel_warn.rb +1 -2
  177. data/lib/rubygems/defaults.rb +15 -1
  178. data/lib/rubygems/dependency.rb +4 -1
  179. data/lib/rubygems/dependency_installer.rb +24 -24
  180. data/lib/rubygems/exceptions.rb +1 -3
  181. data/lib/rubygems/ext/builder.rb +3 -3
  182. data/lib/rubygems/ext/cargo_builder/link_flag_converter.rb +9 -5
  183. data/lib/rubygems/ext/cargo_builder.rb +15 -20
  184. data/lib/rubygems/ext/ext_conf_builder.rb +2 -0
  185. data/lib/rubygems/indexer.rb +1 -1
  186. data/lib/rubygems/installer.rb +5 -5
  187. data/lib/rubygems/optparse/lib/optparse.rb +20 -15
  188. data/lib/rubygems/package/tar_header.rb +11 -11
  189. data/lib/rubygems/platform.rb +0 -2
  190. data/lib/rubygems/request_set/gem_dependency_api.rb +104 -104
  191. data/lib/rubygems/requirement.rb +7 -7
  192. data/lib/rubygems/resolver/installer_set.rb +1 -1
  193. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb +1 -1
  194. data/lib/rubygems/resolver/molinillo/lib/molinillo/errors.rb +32 -26
  195. data/lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb +1 -1
  196. data/lib/rubygems/security/policies.rb +40 -40
  197. data/lib/rubygems/security/trust_dir.rb +1 -1
  198. data/lib/rubygems/security.rb +3 -16
  199. data/lib/rubygems/source.rb +2 -2
  200. data/lib/rubygems/specification.rb +37 -49
  201. data/lib/rubygems/specification_policy.rb +14 -0
  202. data/lib/rubygems/stub_specification.rb +2 -2
  203. data/lib/rubygems/text.rb +1 -1
  204. data/lib/rubygems/tsort/lib/tsort.rb +308 -310
  205. data/lib/rubygems/update_suggestion.rb +69 -0
  206. data/lib/rubygems/util.rb +1 -5
  207. data/lib/rubygems/validator.rb +1 -1
  208. data/lib/rubygems.rb +8 -3
  209. data/rubygems-update.gemspec +2 -2
  210. data/test/rubygems/helper.rb +7 -3
  211. data/test/rubygems/test_bundled_ca.rb +1 -1
  212. data/test/rubygems/test_exit.rb +6 -0
  213. data/test/rubygems/test_gem.rb +4 -9
  214. data/test/rubygems/test_gem_bundler_version_finder.rb +2 -1
  215. data/test/rubygems/test_gem_command_manager.rb +1 -1
  216. data/test/rubygems/test_gem_commands_install_command.rb +19 -0
  217. data/test/rubygems/test_gem_commands_setup_command.rb +1 -8
  218. data/test/rubygems/test_gem_commands_update_command.rb +6 -6
  219. data/test/rubygems/test_gem_config_file.rb +1 -1
  220. data/test/rubygems/test_gem_dependency.rb +2 -0
  221. data/test/rubygems/test_gem_ext_builder.rb +3 -3
  222. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.lock +22 -32
  223. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.toml +1 -1
  224. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock +22 -32
  225. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml +1 -1
  226. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs +12 -0
  227. data/test/rubygems/test_gem_ext_cargo_builder.rb +22 -27
  228. data/test/rubygems/test_gem_ext_cargo_builder_link_flag_converter.rb +16 -16
  229. data/test/rubygems/test_gem_ext_cargo_builder_unit.rb +0 -10
  230. data/test/rubygems/test_gem_indexer.rb +39 -20
  231. data/test/rubygems/test_gem_installer.rb +68 -2
  232. data/test/rubygems/test_gem_package_tar_header.rb +13 -13
  233. data/test/rubygems/test_gem_platform.rb +59 -60
  234. data/test/rubygems/test_gem_remote_fetcher.rb +4 -4
  235. data/test/rubygems/test_gem_request_set.rb +2 -2
  236. data/test/rubygems/test_gem_requirement.rb +1 -1
  237. data/test/rubygems/test_gem_resolver_api_set.rb +12 -12
  238. data/test/rubygems/test_gem_resolver_api_specification.rb +19 -19
  239. data/test/rubygems/test_gem_resolver_git_specification.rb +1 -1
  240. data/test/rubygems/test_gem_security_policy.rb +10 -10
  241. data/test/rubygems/test_gem_security_trust_dir.rb +2 -2
  242. data/test/rubygems/test_gem_specification.rb +50 -37
  243. data/test/rubygems/test_gem_uninstaller.rb +1 -1
  244. data/test/rubygems/test_gem_update_suggestion.rb +208 -0
  245. data/test/rubygems/test_kernel.rb +10 -8
  246. data/test/rubygems/test_require.rb +70 -55
  247. metadata +34 -31
  248. data/bundler/lib/bundler/templates/newgem/travis.yml.tt +0 -6
  249. data/bundler/lib/bundler/vendor/molinillo/LICENSE +0 -9
  250. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +0 -57
  251. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +0 -88
  252. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +0 -36
  253. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +0 -66
  254. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +0 -62
  255. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +0 -63
  256. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +0 -61
  257. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +0 -126
  258. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +0 -46
  259. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +0 -36
  260. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +0 -164
  261. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +0 -255
  262. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +0 -149
  263. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +0 -6
  264. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +0 -112
  265. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb +0 -67
  266. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +0 -839
  267. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +0 -46
  268. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +0 -58
  269. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo.rb +0 -11
  270. data/bundler/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +0 -154
  271. data/bundler/lib/bundler/vendored_molinillo.rb +0 -4
  272. data/bundler/lib/bundler/version_ranges.rb +0 -122
@@ -121,334 +121,332 @@
121
121
  # <em>SIAM Journal on Computing</em>, Vol. 1, No. 2, pp. 146-160, June 1972.
122
122
  #
123
123
 
124
- module Gem
125
- module TSort
126
- class Cyclic < StandardError
127
- end
128
-
129
- # Returns a topologically sorted array of nodes.
130
- # The array is sorted from children to parents, i.e.
131
- # the first element has no child and the last node has no parent.
132
- #
133
- # If there is a cycle, Gem::TSort::Cyclic is raised.
134
- #
135
- # class G
136
- # include Gem::TSort
137
- # def initialize(g)
138
- # @g = g
139
- # end
140
- # def tsort_each_child(n, &b) @g[n].each(&b) end
141
- # def tsort_each_node(&b) @g.each_key(&b) end
142
- # end
143
- #
144
- # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
145
- # p graph.tsort #=> [4, 2, 3, 1]
146
- #
147
- # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
148
- # p graph.tsort # raises Gem::TSort::Cyclic
149
- #
150
- def tsort
151
- each_node = method(:tsort_each_node)
152
- each_child = method(:tsort_each_child)
153
- Gem::TSort.tsort(each_node, each_child)
154
- end
124
+ module Gem::TSort
125
+ class Cyclic < StandardError
126
+ end
155
127
 
156
- # Returns a topologically sorted array of nodes.
157
- # The array is sorted from children to parents, i.e.
158
- # the first element has no child and the last node has no parent.
159
- #
160
- # The graph is represented by _each_node_ and _each_child_.
161
- # _each_node_ should have +call+ method which yields for each node in the graph.
162
- # _each_child_ should have +call+ method which takes a node argument and yields for each child node.
163
- #
164
- # If there is a cycle, Gem::TSort::Cyclic is raised.
165
- #
166
- # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
167
- # each_node = lambda {|&b| g.each_key(&b) }
168
- # each_child = lambda {|n, &b| g[n].each(&b) }
169
- # p Gem::TSort.tsort(each_node, each_child) #=> [4, 2, 3, 1]
170
- #
171
- # g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
172
- # each_node = lambda {|&b| g.each_key(&b) }
173
- # each_child = lambda {|n, &b| g[n].each(&b) }
174
- # p Gem::TSort.tsort(each_node, each_child) # raises Gem::TSort::Cyclic
175
- #
176
- def TSort.tsort(each_node, each_child)
177
- Gem::TSort.tsort_each(each_node, each_child).to_a
178
- end
128
+ # Returns a topologically sorted array of nodes.
129
+ # The array is sorted from children to parents, i.e.
130
+ # the first element has no child and the last node has no parent.
131
+ #
132
+ # If there is a cycle, Gem::TSort::Cyclic is raised.
133
+ #
134
+ # class G
135
+ # include Gem::TSort
136
+ # def initialize(g)
137
+ # @g = g
138
+ # end
139
+ # def tsort_each_child(n, &b) @g[n].each(&b) end
140
+ # def tsort_each_node(&b) @g.each_key(&b) end
141
+ # end
142
+ #
143
+ # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
144
+ # p graph.tsort #=> [4, 2, 3, 1]
145
+ #
146
+ # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
147
+ # p graph.tsort # raises Gem::TSort::Cyclic
148
+ #
149
+ def tsort
150
+ each_node = method(:tsort_each_node)
151
+ each_child = method(:tsort_each_child)
152
+ Gem::TSort.tsort(each_node, each_child)
153
+ end
179
154
 
180
- # The iterator version of the #tsort method.
181
- # <tt><em>obj</em>.tsort_each</tt> is similar to <tt><em>obj</em>.tsort.each</tt>, but
182
- # modification of _obj_ during the iteration may lead to unexpected results.
183
- #
184
- # #tsort_each returns +nil+.
185
- # If there is a cycle, Gem::TSort::Cyclic is raised.
186
- #
187
- # class G
188
- # include Gem::TSort
189
- # def initialize(g)
190
- # @g = g
191
- # end
192
- # def tsort_each_child(n, &b) @g[n].each(&b) end
193
- # def tsort_each_node(&b) @g.each_key(&b) end
194
- # end
195
- #
196
- # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
197
- # graph.tsort_each {|n| p n }
198
- # #=> 4
199
- # # 2
200
- # # 3
201
- # # 1
202
- #
203
- def tsort_each(&block) # :yields: node
204
- each_node = method(:tsort_each_node)
205
- each_child = method(:tsort_each_child)
206
- Gem::TSort.tsort_each(each_node, each_child, &block)
207
- end
155
+ # Returns a topologically sorted array of nodes.
156
+ # The array is sorted from children to parents, i.e.
157
+ # the first element has no child and the last node has no parent.
158
+ #
159
+ # The graph is represented by _each_node_ and _each_child_.
160
+ # _each_node_ should have +call+ method which yields for each node in the graph.
161
+ # _each_child_ should have +call+ method which takes a node argument and yields for each child node.
162
+ #
163
+ # If there is a cycle, Gem::TSort::Cyclic is raised.
164
+ #
165
+ # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
166
+ # each_node = lambda {|&b| g.each_key(&b) }
167
+ # each_child = lambda {|n, &b| g[n].each(&b) }
168
+ # p Gem::TSort.tsort(each_node, each_child) #=> [4, 2, 3, 1]
169
+ #
170
+ # g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
171
+ # each_node = lambda {|&b| g.each_key(&b) }
172
+ # each_child = lambda {|n, &b| g[n].each(&b) }
173
+ # p Gem::TSort.tsort(each_node, each_child) # raises Gem::TSort::Cyclic
174
+ #
175
+ def self.tsort(each_node, each_child)
176
+ tsort_each(each_node, each_child).to_a
177
+ end
208
178
 
209
- # The iterator version of the Gem::TSort.tsort method.
210
- #
211
- # The graph is represented by _each_node_ and _each_child_.
212
- # _each_node_ should have +call+ method which yields for each node in the graph.
213
- # _each_child_ should have +call+ method which takes a node argument and yields for each child node.
214
- #
215
- # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
216
- # each_node = lambda {|&b| g.each_key(&b) }
217
- # each_child = lambda {|n, &b| g[n].each(&b) }
218
- # Gem::TSort.tsort_each(each_node, each_child) {|n| p n }
219
- # #=> 4
220
- # # 2
221
- # # 3
222
- # # 1
223
- #
224
- def TSort.tsort_each(each_node, each_child) # :yields: node
225
- return to_enum(__method__, each_node, each_child) unless block_given?
179
+ # The iterator version of the #tsort method.
180
+ # <tt><em>obj</em>.tsort_each</tt> is similar to <tt><em>obj</em>.tsort.each</tt>, but
181
+ # modification of _obj_ during the iteration may lead to unexpected results.
182
+ #
183
+ # #tsort_each returns +nil+.
184
+ # If there is a cycle, Gem::TSort::Cyclic is raised.
185
+ #
186
+ # class G
187
+ # include Gem::TSort
188
+ # def initialize(g)
189
+ # @g = g
190
+ # end
191
+ # def tsort_each_child(n, &b) @g[n].each(&b) end
192
+ # def tsort_each_node(&b) @g.each_key(&b) end
193
+ # end
194
+ #
195
+ # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
196
+ # graph.tsort_each {|n| p n }
197
+ # #=> 4
198
+ # # 2
199
+ # # 3
200
+ # # 1
201
+ #
202
+ def tsort_each(&block) # :yields: node
203
+ each_node = method(:tsort_each_node)
204
+ each_child = method(:tsort_each_child)
205
+ Gem::TSort.tsort_each(each_node, each_child, &block)
206
+ end
226
207
 
227
- Gem::TSort.each_strongly_connected_component(each_node, each_child) {|component|
228
- if component.size == 1
229
- yield component.first
230
- else
231
- raise Cyclic.new("topological sort failed: #{component.inspect}")
232
- end
233
- }
234
- end
208
+ # The iterator version of the Gem::TSort.tsort method.
209
+ #
210
+ # The graph is represented by _each_node_ and _each_child_.
211
+ # _each_node_ should have +call+ method which yields for each node in the graph.
212
+ # _each_child_ should have +call+ method which takes a node argument and yields for each child node.
213
+ #
214
+ # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
215
+ # each_node = lambda {|&b| g.each_key(&b) }
216
+ # each_child = lambda {|n, &b| g[n].each(&b) }
217
+ # Gem::TSort.tsort_each(each_node, each_child) {|n| p n }
218
+ # #=> 4
219
+ # # 2
220
+ # # 3
221
+ # # 1
222
+ #
223
+ def self.tsort_each(each_node, each_child) # :yields: node
224
+ return to_enum(__method__, each_node, each_child) unless block_given?
235
225
 
236
- # Returns strongly connected components as an array of arrays of nodes.
237
- # The array is sorted from children to parents.
238
- # Each elements of the array represents a strongly connected component.
239
- #
240
- # class G
241
- # include Gem::TSort
242
- # def initialize(g)
243
- # @g = g
244
- # end
245
- # def tsort_each_child(n, &b) @g[n].each(&b) end
246
- # def tsort_each_node(&b) @g.each_key(&b) end
247
- # end
248
- #
249
- # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
250
- # p graph.strongly_connected_components #=> [[4], [2], [3], [1]]
251
- #
252
- # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
253
- # p graph.strongly_connected_components #=> [[4], [2, 3], [1]]
254
- #
255
- def strongly_connected_components
256
- each_node = method(:tsort_each_node)
257
- each_child = method(:tsort_each_child)
258
- Gem::TSort.strongly_connected_components(each_node, each_child)
259
- end
226
+ each_strongly_connected_component(each_node, each_child) {|component|
227
+ if component.size == 1
228
+ yield component.first
229
+ else
230
+ raise Cyclic.new("topological sort failed: #{component.inspect}")
231
+ end
232
+ }
233
+ end
260
234
 
261
- # Returns strongly connected components as an array of arrays of nodes.
262
- # The array is sorted from children to parents.
263
- # Each elements of the array represents a strongly connected component.
264
- #
265
- # The graph is represented by _each_node_ and _each_child_.
266
- # _each_node_ should have +call+ method which yields for each node in the graph.
267
- # _each_child_ should have +call+ method which takes a node argument and yields for each child node.
268
- #
269
- # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
270
- # each_node = lambda {|&b| g.each_key(&b) }
271
- # each_child = lambda {|n, &b| g[n].each(&b) }
272
- # p Gem::TSort.strongly_connected_components(each_node, each_child)
273
- # #=> [[4], [2], [3], [1]]
274
- #
275
- # g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
276
- # each_node = lambda {|&b| g.each_key(&b) }
277
- # each_child = lambda {|n, &b| g[n].each(&b) }
278
- # p Gem::TSort.strongly_connected_components(each_node, each_child)
279
- # #=> [[4], [2, 3], [1]]
280
- #
281
- def TSort.strongly_connected_components(each_node, each_child)
282
- Gem::TSort.each_strongly_connected_component(each_node, each_child).to_a
283
- end
235
+ # Returns strongly connected components as an array of arrays of nodes.
236
+ # The array is sorted from children to parents.
237
+ # Each elements of the array represents a strongly connected component.
238
+ #
239
+ # class G
240
+ # include Gem::TSort
241
+ # def initialize(g)
242
+ # @g = g
243
+ # end
244
+ # def tsort_each_child(n, &b) @g[n].each(&b) end
245
+ # def tsort_each_node(&b) @g.each_key(&b) end
246
+ # end
247
+ #
248
+ # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
249
+ # p graph.strongly_connected_components #=> [[4], [2], [3], [1]]
250
+ #
251
+ # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
252
+ # p graph.strongly_connected_components #=> [[4], [2, 3], [1]]
253
+ #
254
+ def strongly_connected_components
255
+ each_node = method(:tsort_each_node)
256
+ each_child = method(:tsort_each_child)
257
+ Gem::TSort.strongly_connected_components(each_node, each_child)
258
+ end
284
259
 
285
- # The iterator version of the #strongly_connected_components method.
286
- # <tt><em>obj</em>.each_strongly_connected_component</tt> is similar to
287
- # <tt><em>obj</em>.strongly_connected_components.each</tt>, but
288
- # modification of _obj_ during the iteration may lead to unexpected results.
289
- #
290
- # #each_strongly_connected_component returns +nil+.
291
- #
292
- # class G
293
- # include Gem::TSort
294
- # def initialize(g)
295
- # @g = g
296
- # end
297
- # def tsort_each_child(n, &b) @g[n].each(&b) end
298
- # def tsort_each_node(&b) @g.each_key(&b) end
299
- # end
300
- #
301
- # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
302
- # graph.each_strongly_connected_component {|scc| p scc }
303
- # #=> [4]
304
- # # [2]
305
- # # [3]
306
- # # [1]
307
- #
308
- # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
309
- # graph.each_strongly_connected_component {|scc| p scc }
310
- # #=> [4]
311
- # # [2, 3]
312
- # # [1]
313
- #
314
- def each_strongly_connected_component(&block) # :yields: nodes
315
- each_node = method(:tsort_each_node)
316
- each_child = method(:tsort_each_child)
317
- Gem::TSort.each_strongly_connected_component(each_node, each_child, &block)
318
- end
260
+ # Returns strongly connected components as an array of arrays of nodes.
261
+ # The array is sorted from children to parents.
262
+ # Each elements of the array represents a strongly connected component.
263
+ #
264
+ # The graph is represented by _each_node_ and _each_child_.
265
+ # _each_node_ should have +call+ method which yields for each node in the graph.
266
+ # _each_child_ should have +call+ method which takes a node argument and yields for each child node.
267
+ #
268
+ # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
269
+ # each_node = lambda {|&b| g.each_key(&b) }
270
+ # each_child = lambda {|n, &b| g[n].each(&b) }
271
+ # p Gem::TSort.strongly_connected_components(each_node, each_child)
272
+ # #=> [[4], [2], [3], [1]]
273
+ #
274
+ # g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
275
+ # each_node = lambda {|&b| g.each_key(&b) }
276
+ # each_child = lambda {|n, &b| g[n].each(&b) }
277
+ # p Gem::TSort.strongly_connected_components(each_node, each_child)
278
+ # #=> [[4], [2, 3], [1]]
279
+ #
280
+ def self.strongly_connected_components(each_node, each_child)
281
+ each_strongly_connected_component(each_node, each_child).to_a
282
+ end
319
283
 
320
- # The iterator version of the Gem::TSort.strongly_connected_components method.
321
- #
322
- # The graph is represented by _each_node_ and _each_child_.
323
- # _each_node_ should have +call+ method which yields for each node in the graph.
324
- # _each_child_ should have +call+ method which takes a node argument and yields for each child node.
325
- #
326
- # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
327
- # each_node = lambda {|&b| g.each_key(&b) }
328
- # each_child = lambda {|n, &b| g[n].each(&b) }
329
- # Gem::TSort.each_strongly_connected_component(each_node, each_child) {|scc| p scc }
330
- # #=> [4]
331
- # # [2]
332
- # # [3]
333
- # # [1]
334
- #
335
- # g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
336
- # each_node = lambda {|&b| g.each_key(&b) }
337
- # each_child = lambda {|n, &b| g[n].each(&b) }
338
- # Gem::TSort.each_strongly_connected_component(each_node, each_child) {|scc| p scc }
339
- # #=> [4]
340
- # # [2, 3]
341
- # # [1]
342
- #
343
- def TSort.each_strongly_connected_component(each_node, each_child) # :yields: nodes
344
- return to_enum(__method__, each_node, each_child) unless block_given?
284
+ # The iterator version of the #strongly_connected_components method.
285
+ # <tt><em>obj</em>.each_strongly_connected_component</tt> is similar to
286
+ # <tt><em>obj</em>.strongly_connected_components.each</tt>, but
287
+ # modification of _obj_ during the iteration may lead to unexpected results.
288
+ #
289
+ # #each_strongly_connected_component returns +nil+.
290
+ #
291
+ # class G
292
+ # include Gem::TSort
293
+ # def initialize(g)
294
+ # @g = g
295
+ # end
296
+ # def tsort_each_child(n, &b) @g[n].each(&b) end
297
+ # def tsort_each_node(&b) @g.each_key(&b) end
298
+ # end
299
+ #
300
+ # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
301
+ # graph.each_strongly_connected_component {|scc| p scc }
302
+ # #=> [4]
303
+ # # [2]
304
+ # # [3]
305
+ # # [1]
306
+ #
307
+ # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
308
+ # graph.each_strongly_connected_component {|scc| p scc }
309
+ # #=> [4]
310
+ # # [2, 3]
311
+ # # [1]
312
+ #
313
+ def each_strongly_connected_component(&block) # :yields: nodes
314
+ each_node = method(:tsort_each_node)
315
+ each_child = method(:tsort_each_child)
316
+ Gem::TSort.each_strongly_connected_component(each_node, each_child, &block)
317
+ end
345
318
 
346
- id_map = {}
347
- stack = []
348
- each_node.call {|node|
349
- unless id_map.include? node
350
- Gem::TSort.each_strongly_connected_component_from(node, each_child, id_map, stack) {|c|
351
- yield c
352
- }
353
- end
354
- }
355
- nil
356
- end
319
+ # The iterator version of the Gem::TSort.strongly_connected_components method.
320
+ #
321
+ # The graph is represented by _each_node_ and _each_child_.
322
+ # _each_node_ should have +call+ method which yields for each node in the graph.
323
+ # _each_child_ should have +call+ method which takes a node argument and yields for each child node.
324
+ #
325
+ # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
326
+ # each_node = lambda {|&b| g.each_key(&b) }
327
+ # each_child = lambda {|n, &b| g[n].each(&b) }
328
+ # Gem::TSort.each_strongly_connected_component(each_node, each_child) {|scc| p scc }
329
+ # #=> [4]
330
+ # # [2]
331
+ # # [3]
332
+ # # [1]
333
+ #
334
+ # g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
335
+ # each_node = lambda {|&b| g.each_key(&b) }
336
+ # each_child = lambda {|n, &b| g[n].each(&b) }
337
+ # Gem::TSort.each_strongly_connected_component(each_node, each_child) {|scc| p scc }
338
+ # #=> [4]
339
+ # # [2, 3]
340
+ # # [1]
341
+ #
342
+ def self.each_strongly_connected_component(each_node, each_child) # :yields: nodes
343
+ return to_enum(__method__, each_node, each_child) unless block_given?
357
344
 
358
- # Iterates over strongly connected component in the subgraph reachable from
359
- # _node_.
360
- #
361
- # Return value is unspecified.
362
- #
363
- # #each_strongly_connected_component_from doesn't call #tsort_each_node.
364
- #
365
- # class G
366
- # include Gem::TSort
367
- # def initialize(g)
368
- # @g = g
369
- # end
370
- # def tsort_each_child(n, &b) @g[n].each(&b) end
371
- # def tsort_each_node(&b) @g.each_key(&b) end
372
- # end
373
- #
374
- # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
375
- # graph.each_strongly_connected_component_from(2) {|scc| p scc }
376
- # #=> [4]
377
- # # [2]
378
- #
379
- # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
380
- # graph.each_strongly_connected_component_from(2) {|scc| p scc }
381
- # #=> [4]
382
- # # [2, 3]
383
- #
384
- def each_strongly_connected_component_from(node, id_map={}, stack=[], &block) # :yields: nodes
385
- Gem::TSort.each_strongly_connected_component_from(node, method(:tsort_each_child), id_map, stack, &block)
386
- end
345
+ id_map = {}
346
+ stack = []
347
+ each_node.call {|node|
348
+ unless id_map.include? node
349
+ each_strongly_connected_component_from(node, each_child, id_map, stack) {|c|
350
+ yield c
351
+ }
352
+ end
353
+ }
354
+ nil
355
+ end
387
356
 
388
- # Iterates over strongly connected components in a graph.
389
- # The graph is represented by _node_ and _each_child_.
390
- #
391
- # _node_ is the first node.
392
- # _each_child_ should have +call+ method which takes a node argument
393
- # and yields for each child node.
394
- #
395
- # Return value is unspecified.
396
- #
397
- # #Gem::TSort.each_strongly_connected_component_from is a class method and
398
- # it doesn't need a class to represent a graph which includes Gem::TSort.
399
- #
400
- # graph = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
401
- # each_child = lambda {|n, &b| graph[n].each(&b) }
402
- # Gem::TSort.each_strongly_connected_component_from(1, each_child) {|scc|
403
- # p scc
404
- # }
405
- # #=> [4]
406
- # # [2, 3]
407
- # # [1]
408
- #
409
- def TSort.each_strongly_connected_component_from(node, each_child, id_map={}, stack=[]) # :yields: nodes
410
- return to_enum(__method__, node, each_child, id_map, stack) unless block_given?
357
+ # Iterates over strongly connected component in the subgraph reachable from
358
+ # _node_.
359
+ #
360
+ # Return value is unspecified.
361
+ #
362
+ # #each_strongly_connected_component_from doesn't call #tsort_each_node.
363
+ #
364
+ # class G
365
+ # include Gem::TSort
366
+ # def initialize(g)
367
+ # @g = g
368
+ # end
369
+ # def tsort_each_child(n, &b) @g[n].each(&b) end
370
+ # def tsort_each_node(&b) @g.each_key(&b) end
371
+ # end
372
+ #
373
+ # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
374
+ # graph.each_strongly_connected_component_from(2) {|scc| p scc }
375
+ # #=> [4]
376
+ # # [2]
377
+ #
378
+ # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
379
+ # graph.each_strongly_connected_component_from(2) {|scc| p scc }
380
+ # #=> [4]
381
+ # # [2, 3]
382
+ #
383
+ def each_strongly_connected_component_from(node, id_map={}, stack=[], &block) # :yields: nodes
384
+ Gem::TSort.each_strongly_connected_component_from(node, method(:tsort_each_child), id_map, stack, &block)
385
+ end
411
386
 
412
- minimum_id = node_id = id_map[node] = id_map.size
413
- stack_length = stack.length
414
- stack << node
387
+ # Iterates over strongly connected components in a graph.
388
+ # The graph is represented by _node_ and _each_child_.
389
+ #
390
+ # _node_ is the first node.
391
+ # _each_child_ should have +call+ method which takes a node argument
392
+ # and yields for each child node.
393
+ #
394
+ # Return value is unspecified.
395
+ #
396
+ # #Gem::TSort.each_strongly_connected_component_from is a class method and
397
+ # it doesn't need a class to represent a graph which includes Gem::TSort.
398
+ #
399
+ # graph = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
400
+ # each_child = lambda {|n, &b| graph[n].each(&b) }
401
+ # Gem::TSort.each_strongly_connected_component_from(1, each_child) {|scc|
402
+ # p scc
403
+ # }
404
+ # #=> [4]
405
+ # # [2, 3]
406
+ # # [1]
407
+ #
408
+ def self.each_strongly_connected_component_from(node, each_child, id_map={}, stack=[]) # :yields: nodes
409
+ return to_enum(__method__, node, each_child, id_map, stack) unless block_given?
415
410
 
416
- each_child.call(node) {|child|
417
- if id_map.include? child
418
- child_id = id_map[child]
419
- minimum_id = child_id if child_id && child_id < minimum_id
420
- else
421
- sub_minimum_id =
422
- Gem::TSort.each_strongly_connected_component_from(child, each_child, id_map, stack) {|c|
423
- yield c
424
- }
425
- minimum_id = sub_minimum_id if sub_minimum_id < minimum_id
426
- end
427
- }
411
+ minimum_id = node_id = id_map[node] = id_map.size
412
+ stack_length = stack.length
413
+ stack << node
428
414
 
429
- if node_id == minimum_id
430
- component = stack.slice!(stack_length .. -1)
431
- component.each {|n| id_map[n] = nil}
432
- yield component
415
+ each_child.call(node) {|child|
416
+ if id_map.include? child
417
+ child_id = id_map[child]
418
+ minimum_id = child_id if child_id && child_id < minimum_id
419
+ else
420
+ sub_minimum_id =
421
+ each_strongly_connected_component_from(child, each_child, id_map, stack) {|c|
422
+ yield c
423
+ }
424
+ minimum_id = sub_minimum_id if sub_minimum_id < minimum_id
433
425
  end
426
+ }
434
427
 
435
- minimum_id
428
+ if node_id == minimum_id
429
+ component = stack.slice!(stack_length .. -1)
430
+ component.each {|n| id_map[n] = nil}
431
+ yield component
436
432
  end
437
433
 
438
- # Should be implemented by a extended class.
439
- #
440
- # #tsort_each_node is used to iterate for all nodes over a graph.
441
- #
442
- def tsort_each_node # :yields: node
443
- raise NotImplementedError.new
444
- end
434
+ minimum_id
435
+ end
445
436
 
446
- # Should be implemented by a extended class.
447
- #
448
- # #tsort_each_child is used to iterate for child nodes of _node_.
449
- #
450
- def tsort_each_child(node) # :yields: child
451
- raise NotImplementedError.new
452
- end
437
+ # Should be implemented by a extended class.
438
+ #
439
+ # #tsort_each_node is used to iterate for all nodes over a graph.
440
+ #
441
+ def tsort_each_node # :yields: node
442
+ raise NotImplementedError.new
443
+ end
444
+
445
+ # Should be implemented by a extended class.
446
+ #
447
+ # #tsort_each_child is used to iterate for child nodes of _node_.
448
+ #
449
+ def tsort_each_child(node) # :yields: child
450
+ raise NotImplementedError.new
453
451
  end
454
452
  end