sorting 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -27,6 +27,14 @@ Sort a list of Person objects
27
27
  [Sorting.asc(person.first_name), Sorting.asc(person.last_name), Sorting.desc(person.age)]
28
28
  }
29
29
 
30
+ # Care about expensive comparison values which may not always be needed
31
+ # assume item.expensive_value takes a lot of time to compute, but since it's the second value,
32
+ # it might only be needed in a small number of cases.
33
+ require 'sorting/convenience'
34
+ items.sort_by { |item|
35
+ [asc(item.cheap_value), asc(:nils_last) { item.expensive_value }]
36
+ }
37
+
30
38
  # Care about nil values in your data
31
39
  require 'sorting/convenience'
32
40
  people.sort_by { |person|
@@ -36,14 +44,6 @@ Sort a list of Person objects
36
44
  # Only care about nil values in your data
37
45
  [5,3,nil,9].sort_by { |x| x || Sorting::Bigger } # Sorting::Smaller is available too
38
46
 
39
- # Care about expensive comparison values which may not always be needed
40
- # assume item.expensive_value takes a lot of time to compute, but since it's the second value,
41
- # it might only be needed in a small number of cases.
42
- require 'sorting/convenience'
43
- items.sort_by { |item|
44
- [asc(item.cheap_value), asc(:nils_last) { item.expensive_value }]
45
- }
46
-
47
47
  Take a look at {file:documentation/examples.rb} for more examples.
48
48
 
49
49
 
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+
3
+ begin
4
+ require 'sorting/convenience'
5
+ rescue LoadError
6
+ $LOAD_PATH << (p File.expand_path('../../lib', __FILE__))
7
+ require 'sorting/convenience'
8
+ puts "Sorting gem is not installed, using relative lib"
9
+ end
10
+
11
+
12
+ require 'pp'
13
+ Person = Struct.new(:first_name, :last_name, :age)
14
+ people = [
15
+ Person.new('Peter', 'Pan', 15),
16
+ Person.new('Peter', 'Parker', 15),
17
+ Person.new('Peter', 'Pan', 23),
18
+ ]
19
+ pp people.sort_by { |person| [asc(person.first_name), asc(person.last_name), desc(person.age)] }
20
+
21
+
22
+ Foo = Struct.new(:a, :b, :c)
23
+ calc = proc { |s,x| sleep(s); x }
24
+ foos = [
25
+ Foo.new(1,2,1),
26
+ Foo.new(1,2,2),
27
+ Foo.new(1,3,4),
28
+ Foo.new(2,3,4),
29
+ ]
30
+ start = Time.now
31
+ pp foos.sort_by { |x| [asc(x.a), desc(calc[0.1, x.b]), asc(calc[0.2, x.c])] }
32
+ stop = Time.now
33
+ printf "Elapsed: %.2fs\n", stop-start
34
+
35
+ start = Time.now
36
+ pp foos.sort_by { |x| [asc(x.a), desc { calc[0.1, x.b] }, asc { calc[0.2, x.c] }] }
37
+ stop = Time.now
38
+ printf "Elapsed: %.2fs\n", stop-start
@@ -14,6 +14,9 @@ require 'sorting/version'
14
14
  # Sorting
15
15
  # Helpful functionality for sorting and comparing.
16
16
  #
17
+ # Requiring 'sorting' loads all functionality this gem provides, except for the
18
+ # patches on Kernel. For those you must `require 'sorting/convenience'`.
19
+ #
17
20
  # @example Convenient
18
21
  # require 'sorting/convenience'
19
22
  # people.sort_by { |person| [asc(person.first_name), asc(person.last_name), desc(person.age)] }
@@ -24,6 +27,14 @@ require 'sorting/version'
24
27
  # [Sorting.asc(person.first_name), Sorting.asc(person.last_name), Sorting.desc(person.age)]
25
28
  # }
26
29
  #
30
+ # @example Care about expensive comparison values which may not always be needed
31
+ # # assume item.expensive_value takes a lot of time to compute, but since it's the second value,
32
+ # # it might only be needed in a small number of cases.
33
+ # require 'sorting/convenience'
34
+ # items.sort_by { |item|
35
+ # [asc(item.cheap_value), asc(:nils_last) { item.expensive_value }]
36
+ # }
37
+ #
27
38
  # @example Care about nil values in your data
28
39
  # require 'sorting/convenience'
29
40
  # people.sort_by { |person|
@@ -33,15 +44,22 @@ require 'sorting/version'
33
44
  # @example Only care about nil values in your data
34
45
  # [5,3,nil,9].sort_by { |x| x || Sorting::Bigger } # Sorting::Smaller is available too
35
46
  #
36
- # @example Care about expensive comparison values which may not always be needed
37
- # # assume item.expensive_value takes a lot of time to compute, but since it's the second value,
38
- # # it might only be needed in a small number of cases.
39
- # require 'sorting/convenience'
40
- # items.sort_by { |item|
41
- # [asc(item.cheap_value), asc(:nils_last) { item.expensive_value }]
42
- # }
43
- #
44
47
  module Sorting
45
- class_eval(&Sorting::Helpers::MethodDefinitions)
46
- module_function *Sorting::Helpers.private_instance_methods(false)
48
+ Sorting::Helpers.append_to(self) # can't use include, see Sorting::Helpers.append_to
49
+
50
+ # @!method asc(*args, &lazy)
51
+ # @!scope class
52
+ # @see Sorting::Helpers.asc
53
+ #
54
+ # @note
55
+ # This method is a module function, and as such also available as a
56
+ # private instance method.
57
+
58
+ # @!method desc(*args, &lazy)
59
+ # @!scope class
60
+ # @see Sorting::Helpers.desc
61
+ #
62
+ # @note
63
+ # This method is a module function, and as such also available as a
64
+ # private instance method.
47
65
  end
@@ -14,12 +14,16 @@ module Sorting
14
14
  # Sorting::Helpers is a module which provides you with a convenient .asc
15
15
  # forwarding method
16
16
  #
17
- # @see Sorting#asc
18
- # Sorting#asc is the common way to create a Sorting::Ascending instance
17
+ # @see Sorting.asc
18
+ # Sorting.asc is the common way to create a Sorting::Ascending instance,
19
+ # or if you required 'sorting/convenience', then plain asc via Kernel#asc
19
20
  #
20
21
  # @see Sorting::Descending
21
22
  # Sorting::Descending is the opposite of Sorting::Ascending
22
23
  #
24
+ # @note
25
+ # require 'sorting' loads this class
26
+ #
23
27
  class Ascending
24
28
 
25
29
  # Valid values for the treat_nils parameter of Sorting::Ascending#initialize
@@ -12,6 +12,9 @@ module Sorting
12
12
  #
13
13
  # @see Sorting::Smaller
14
14
  #
15
+ # @note
16
+ # require 'sorting' loads this module
17
+ #
15
18
  module Bigger
16
19
  extend Comparable
17
20
 
@@ -50,6 +53,8 @@ module Sorting
50
53
  # (SR) Figure out why this ended up here. I (SR) think it was due to
51
54
  # some comparison failing without it, but I don't remember which.
52
55
  # The specific case should be documented.
56
+ # It is not due to "somestring" <=> Sorting::Bigger, that inverts
57
+ # the expression to Sorting::Bigger <=> "somestring"
53
58
  #
54
59
  def self.to_str
55
60
  self
@@ -11,8 +11,29 @@ require 'sorting'
11
11
 
12
12
 
13
13
 
14
- # @private
14
+ # The 'sorting/convenience' file patches the Kernel module and adds global
15
+ # `asc()` and `desc()` methods, which work like {Sorting::Helpers.asc} and
16
+ # {Sorting::Helpers.desc}
17
+ #
18
+ # @note
19
+ # you have to require 'sorting/convenience' to load this
20
+ #
15
21
  module Kernel
16
- class_eval(&Sorting::Helpers::MethodDefinitions)
17
- module_function *Sorting::Helpers.private_instance_methods(false)
22
+ Sorting::Helpers.append_to(self) # can't use include, see Sorting::Helpers.append_to
23
+
24
+ # @!method asc(*args, &lazy)
25
+ # @!scope class
26
+ # @see Sorting::Helpers.asc
27
+ #
28
+ # @note
29
+ # This method is a module function, and as such also available as a
30
+ # private instance method.
31
+
32
+ # @!method desc(*args, &lazy)
33
+ # @!scope class
34
+ # @see Sorting::Helpers.desc
35
+ #
36
+ # @note
37
+ # This method is a module function, and as such also available as a
38
+ # private instance method.
18
39
  end
@@ -18,11 +18,15 @@ module Sorting
18
18
  # Sorting::Helpers is a module which provides you with a convenient .desc
19
19
  # forwarding method
20
20
  #
21
- # @see Sorting#desc
22
- # Sorting#desc is the common way to create a Sorting::Ascending instance
21
+ # @see Sorting.desc
22
+ # Sorting.desc is the common way to create a Sorting::Descending instance,
23
+ # or if you required 'sorting/convenience', then plain asc via Kernel#desc
23
24
  #
24
- # @see Sorting::Descending
25
- # Sorting::Descending is the opposite of Sorting::Ascending
25
+ # @see Sorting::Ascending
26
+ # Sorting::Ascending is the opposite of Sorting::Descending
27
+ #
28
+ # @note
29
+ # require 'sorting' loads this class
26
30
  #
27
31
  class Descending < Ascending
28
32
 
@@ -11,13 +11,17 @@ module Sorting
11
11
 
12
12
  # This module provides convenience methods to create Sorting::Ascending and
13
13
  # Sorting::Descending instances.
14
+ #
15
+ # Important: see {Sorting::Helpers.append_to} for how to properly use this
16
+ # module with other modules
17
+ #
18
+ # @note
19
+ # require 'sorting' loads this module
20
+ #
14
21
  module Helpers
15
22
 
16
23
  # The proc with the method definitions of asc and desc.
17
- # They are in a proc so the proc can be class_eval'ed in Sorting and Kernel
18
- # to avoid an issue with methods of modules which are included in another
19
- # module not being properly shared
20
- #
24
+ # See {Sorting::Helpers.append_to} for an explanation.
21
25
  MethodDefinitions = proc {
22
26
 
23
27
  # Convenience method to create a Sorting::Ascending instance.
@@ -25,16 +29,53 @@ module Sorting
25
29
  def asc(*args, &lazy)
26
30
  Sorting::Ascending.new(*args, &lazy)
27
31
  end
28
- private :asc
32
+ module_function :asc
29
33
 
30
34
  # Convenience method to create a Sorting::Descending instance.
31
- # Works exactly the same as {Sorting::Ascending#initialize Descending#initialize}
35
+ # Works exactly the same as {Sorting::Descending#initialize Ascending#initialize}
32
36
  def desc(*args, &lazy)
33
37
  Sorting::Descending.new(*args, &lazy)
34
38
  end
35
- private :desc
39
+ module_function :desc
36
40
  }
37
41
 
38
- class_eval(&MethodDefinitions)
42
+ # Adds the Sorting::Helpers methods 'asc' and 'desc' to the given module.
43
+ # This method class_eval because modules included into modules don't
44
+ # properly share methods
45
+ #
46
+ # @param [Module] mod
47
+ # The class or module on which to append the Sorting::Helpers methods
48
+ #
49
+ # @note
50
+ # The methods are stored in the {Sorting::Helpers::MethodDefinitions}
51
+ # proc. That proc is class_eval'ed in in the module given by the `mod`
52
+ # parameter.
53
+ # It is done that way to avoid an issue with methods of modules which are
54
+ # included in another module not being properly shared
55
+ #
56
+ def self.append_to(mod)
57
+ mod.class_eval(&MethodDefinitions)
58
+ end
59
+
60
+ append_to(self)
61
+
62
+ # @!method asc(*args, &lazy)
63
+ # @!scope class
64
+ # Convenience method to create a Sorting::Ascending instance.
65
+ # Works exactly the same as {Sorting::Ascending#initialize}.
66
+ #
67
+ # @note
68
+ # This method is a module function, and as such also available as a
69
+ # private instance method.
70
+
71
+ # @!method desc(*args, &lazy)
72
+ # @!scope class
73
+ # Convenience method to create a Sorting::Descending instance.
74
+ # Works exactly the same as {Sorting::Ascending#initialize
75
+ # Descending#initialize}.
76
+ #
77
+ # @note
78
+ # This method is a module function, and as such also available as a
79
+ # private instance method.
39
80
  end
40
81
  end
@@ -12,6 +12,9 @@ module Sorting
12
12
  #
13
13
  # @see Sorting::Bigger
14
14
  #
15
+ # @note
16
+ # require 'sorting' loads this module
17
+ #
15
18
  module Smaller
16
19
  extend Comparable
17
20
 
@@ -43,6 +46,8 @@ module Sorting
43
46
  # (SR) Figure out why this ended up here. I (SR) think it was due to
44
47
  # some comparison failing without it, but I don't remember which.
45
48
  # The specific case should be documented.
49
+ # It is not due to "somestring" <=> Sorting::Smaller, that inverts
50
+ # the expression to Sorting::Smaller <=> "somestring"
46
51
  #
47
52
  def self.to_str
48
53
  self
@@ -9,5 +9,8 @@ end
9
9
  module Sorting
10
10
 
11
11
  # The version of the sorting gem.
12
- Version = Gem::Version.new("0.0.1")
12
+ # @note
13
+ # require 'sorting' loads this module
14
+ #
15
+ Version = Gem::Version.new("0.0.2")
13
16
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "sorting"
5
- s.version = "0.0.1"
5
+ s.version = "0.0.2"
6
6
  s.authors = "Stefan Rusterholz"
7
7
  s.email = "stefan.rusterholz@gmail.com"
8
8
  s.homepage = "https://github.com/apeiros/sorting"
@@ -16,6 +16,7 @@ Gem::Specification.new do |s|
16
16
 
17
17
  s.files =
18
18
  Dir['bin/**/*'] +
19
+ Dir['documentation/**/*'] +
19
20
  Dir['lib/**/*'] +
20
21
  Dir['rake/**/*'] +
21
22
  Dir['test/**/*'] +
@@ -26,10 +27,9 @@ Gem::Specification.new do |s|
26
27
  Rakefile
27
28
  README.markdown
28
29
  ]
29
- s.require_paths = %w[lib]
30
+
30
31
  if File.directory?('bin') then
31
- executables = Dir.chdir('bin') { Dir.glob('**/*').select { |f| File.executable?(f) } }
32
- s.executables = executables unless executables.empty?
32
+ s.executables = Dir.chdir('bin') { Dir.glob('**/*').select { |f| File.executable?(f) } }
33
33
  end
34
34
 
35
35
  s.required_ruby_version = ">= 1.9.2"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sorting
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-22 00:00:00.000000000 Z
12
+ date: 2013-02-23 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Helpful functionality for sorting and comparing.
15
15
  email: stefan.rusterholz@gmail.com
@@ -17,6 +17,7 @@ executables: []
17
17
  extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
+ - documentation/examples.rb
20
21
  - lib/sorting/ascending.rb
21
22
  - lib/sorting/bigger.rb
22
23
  - lib/sorting/convenience.rb