hobosupport 0.7.5 → 0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest +1 -1
- data/hobosupport.gemspec +16 -8
- data/lib/hobosupport.rb +4 -4
- data/lib/hobosupport/array.rb +3 -3
- data/lib/hobosupport/enumerable.rb +14 -14
- data/lib/hobosupport/fixes/chronic.rb +2 -2
- data/lib/hobosupport/fixes/module.rb +3 -3
- data/lib/hobosupport/hash.rb +24 -18
- data/lib/hobosupport/implies.rb +5 -5
- data/lib/hobosupport/metaid.rb +1 -1
- data/lib/hobosupport/methodcall.rb +10 -10
- data/lib/hobosupport/methodphitamine.rb +1 -1
- data/lib/hobosupport/module.rb +11 -11
- data/test/hobosupport.rdoctest +5 -5
- data/test/hobosupport/enumerable.rdoctest +13 -15
- data/test/hobosupport/hash.rdoctest +14 -16
- data/test/hobosupport/implies.rdoctest +4 -6
- data/test/hobosupport/metaid.rdoctest +3 -5
- data/test/hobosupport/methodphitamine.rdoctest +1 -3
- data/test/hobosupport/module.rdoctest +23 -25
- metadata +4 -4
data/Manifest
CHANGED
@@ -13,6 +13,7 @@ lib/hobosupport/methodcall.rb
|
|
13
13
|
lib/hobosupport/methodphitamine.rb
|
14
14
|
lib/hobosupport/module.rb
|
15
15
|
lib/hobosupport.rb
|
16
|
+
Manifest
|
16
17
|
Manifest.txt
|
17
18
|
README.txt
|
18
19
|
test/hobosupport/enumerable.rdoctest
|
@@ -22,4 +23,3 @@ test/hobosupport/metaid.rdoctest
|
|
22
23
|
test/hobosupport/methodphitamine.rdoctest
|
23
24
|
test/hobosupport/module.rdoctest
|
24
25
|
test/hobosupport.rdoctest
|
25
|
-
Manifest
|
data/hobosupport.gemspec
CHANGED
@@ -1,27 +1,35 @@
|
|
1
1
|
|
2
|
-
# Gem::Specification for Hobosupport-0.
|
2
|
+
# Gem::Specification for Hobosupport-0.8
|
3
3
|
# Originally generated by Echoe
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = %q{hobosupport}
|
7
|
-
s.version = "0.
|
8
|
-
|
9
|
-
s.specification_version = 2 if s.respond_to? :specification_version=
|
7
|
+
s.version = "0.8"
|
10
8
|
|
11
9
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
10
|
s.authors = ["Tom Locke"]
|
13
|
-
s.date = %q{2008-
|
11
|
+
s.date = %q{2008-09-03}
|
14
12
|
s.description = %q{Core Ruby extensions from the Hobo project}
|
15
13
|
s.email = %q{tom@tomlocke.com}
|
16
14
|
s.extra_rdoc_files = ["lib/hobosupport/array.rb", "lib/hobosupport/blankslate.rb", "lib/hobosupport/enumerable.rb", "lib/hobosupport/fixes/chronic.rb", "lib/hobosupport/fixes/module.rb", "lib/hobosupport/fixes/pp.rb", "lib/hobosupport/fixes.rb", "lib/hobosupport/hash.rb", "lib/hobosupport/implies.rb", "lib/hobosupport/metaid.rb", "lib/hobosupport/methodcall.rb", "lib/hobosupport/methodphitamine.rb", "lib/hobosupport/module.rb", "lib/hobosupport.rb", "README.txt"]
|
17
|
-
s.files = ["CHANGES.txt", "lib/hobosupport/array.rb", "lib/hobosupport/blankslate.rb", "lib/hobosupport/enumerable.rb", "lib/hobosupport/fixes/chronic.rb", "lib/hobosupport/fixes/module.rb", "lib/hobosupport/fixes/pp.rb", "lib/hobosupport/fixes.rb", "lib/hobosupport/hash.rb", "lib/hobosupport/implies.rb", "lib/hobosupport/metaid.rb", "lib/hobosupport/methodcall.rb", "lib/hobosupport/methodphitamine.rb", "lib/hobosupport/module.rb", "lib/hobosupport.rb", "Manifest.txt", "README.txt", "test/hobosupport/enumerable.rdoctest", "test/hobosupport/hash.rdoctest", "test/hobosupport/implies.rdoctest", "test/hobosupport/metaid.rdoctest", "test/hobosupport/methodphitamine.rdoctest", "test/hobosupport/module.rdoctest", "test/hobosupport.rdoctest", "
|
15
|
+
s.files = ["CHANGES.txt", "lib/hobosupport/array.rb", "lib/hobosupport/blankslate.rb", "lib/hobosupport/enumerable.rb", "lib/hobosupport/fixes/chronic.rb", "lib/hobosupport/fixes/module.rb", "lib/hobosupport/fixes/pp.rb", "lib/hobosupport/fixes.rb", "lib/hobosupport/hash.rb", "lib/hobosupport/implies.rb", "lib/hobosupport/metaid.rb", "lib/hobosupport/methodcall.rb", "lib/hobosupport/methodphitamine.rb", "lib/hobosupport/module.rb", "lib/hobosupport.rb", "Manifest", "Manifest.txt", "README.txt", "test/hobosupport/enumerable.rdoctest", "test/hobosupport/hash.rdoctest", "test/hobosupport/implies.rdoctest", "test/hobosupport/metaid.rdoctest", "test/hobosupport/methodphitamine.rdoctest", "test/hobosupport/module.rdoctest", "test/hobosupport.rdoctest", "hobosupport.gemspec"]
|
18
16
|
s.has_rdoc = true
|
19
17
|
s.homepage = %q{http://hobocentral.net/hobosupport}
|
20
18
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Hobosupport", "--main", "README.txt"]
|
21
19
|
s.require_paths = ["lib"]
|
22
20
|
s.rubyforge_project = %q{hobo}
|
23
|
-
s.rubygems_version = %q{1.0
|
21
|
+
s.rubygems_version = %q{1.2.0}
|
24
22
|
s.summary = %q{Core Ruby extensions from the Hobo project}
|
23
|
+
|
24
|
+
if s.respond_to? :specification_version then
|
25
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
26
|
+
s.specification_version = 2
|
27
|
+
|
28
|
+
if current_version >= 3 then
|
29
|
+
else
|
30
|
+
end
|
31
|
+
else
|
32
|
+
end
|
25
33
|
end
|
26
34
|
|
27
35
|
|
@@ -37,5 +45,5 @@ end
|
|
37
45
|
# p.project = "hobo"
|
38
46
|
#
|
39
47
|
# p.changelog = "CHANGES.txt"
|
40
|
-
# p.version = "0.
|
48
|
+
# p.version = "0.8"
|
41
49
|
# end
|
data/lib/hobosupport.rb
CHANGED
@@ -12,9 +12,9 @@ require 'hobosupport/hash'
|
|
12
12
|
require 'hobosupport/module'
|
13
13
|
|
14
14
|
module HoboSupport
|
15
|
-
|
16
|
-
VERSION = "0.
|
17
|
-
|
15
|
+
|
16
|
+
VERSION = "0.8"
|
17
|
+
|
18
18
|
end
|
19
19
|
|
20
20
|
|
@@ -27,5 +27,5 @@ class Object
|
|
27
27
|
def is_a?(*args)
|
28
28
|
args.any? {|a| is_a_without_multiple_args?(a) }
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
end
|
data/lib/hobosupport/array.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
class Array
|
2
|
-
|
2
|
+
|
3
3
|
alias_method :multiply, :*
|
4
|
-
|
4
|
+
|
5
5
|
def *(rhs=nil)
|
6
6
|
if rhs
|
7
7
|
multiply(rhs)
|
@@ -9,7 +9,7 @@ class Array
|
|
9
9
|
Enumerable::MultiSender.new(self, :map)
|
10
10
|
end
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
def drop_while!
|
14
14
|
drop = 0
|
15
15
|
drop += 1 while yield(self[drop])
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Enumerable
|
2
2
|
|
3
|
-
def
|
3
|
+
def map_and_find(not_found=nil)
|
4
4
|
each do |x|
|
5
5
|
val = yield(x)
|
6
6
|
return val if val
|
@@ -13,7 +13,7 @@ module Enumerable
|
|
13
13
|
each_with_index {|x, i| res << yield(x, i)}
|
14
14
|
res
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
def build_hash
|
18
18
|
res = {}
|
19
19
|
each do |x|
|
@@ -22,7 +22,7 @@ module Enumerable
|
|
22
22
|
end
|
23
23
|
res
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
def map_hash
|
27
27
|
res = {}
|
28
28
|
each do |x|
|
@@ -31,13 +31,13 @@ module Enumerable
|
|
31
31
|
end
|
32
32
|
res
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
def rest
|
36
36
|
self[1..-1]
|
37
37
|
end
|
38
38
|
|
39
39
|
class MultiSender
|
40
|
-
|
40
|
+
|
41
41
|
undef_method(*(instance_methods - %w*__id__ __send__*))
|
42
42
|
|
43
43
|
def initialize(enumerable, method)
|
@@ -48,32 +48,32 @@ module Enumerable
|
|
48
48
|
def method_missing(name, *args, &block)
|
49
49
|
@enumerable.send(@method) { |x| x.send(name, *args, &block) }
|
50
50
|
end
|
51
|
-
|
51
|
+
|
52
52
|
end
|
53
|
-
|
53
|
+
|
54
54
|
def *()
|
55
55
|
MultiSender.new(self, :map)
|
56
56
|
end
|
57
|
-
|
57
|
+
|
58
58
|
def where
|
59
59
|
MultiSender.new(self, :select)
|
60
60
|
end
|
61
|
-
|
61
|
+
|
62
62
|
def where_not
|
63
63
|
MultiSender.new(self, :reject)
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
def drop_while
|
67
67
|
drop = 0
|
68
68
|
drop += 1 while yield(self[drop])
|
69
|
-
self[drop..-1]
|
69
|
+
self[drop..-1]
|
70
70
|
end
|
71
|
-
|
71
|
+
|
72
72
|
|
73
73
|
def take_while
|
74
74
|
take = 0
|
75
75
|
take += 1 while yield(self[take])
|
76
|
-
self[0..take-1]
|
76
|
+
self[0..take-1]
|
77
77
|
end
|
78
78
|
|
79
79
|
end
|
@@ -88,5 +88,5 @@ class Object
|
|
88
88
|
def not_in?(enum)
|
89
89
|
enum.nil? || !enum.include?(self)
|
90
90
|
end
|
91
|
-
|
91
|
+
|
92
92
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
class Module
|
2
|
-
|
2
|
+
|
3
3
|
# Custom alias_method_chain that won't cause inifinite recursion if
|
4
4
|
# called twice.
|
5
5
|
# Calling alias_method_chain on alias_method_chain
|
@@ -16,7 +16,7 @@ class Module
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
|
19
|
+
|
20
20
|
# Fix delegate so it doesn't go bang if 'to' is nil
|
21
21
|
def delegate(*methods)
|
22
22
|
options = methods.pop
|
@@ -33,5 +33,5 @@ class Module
|
|
33
33
|
EOS
|
34
34
|
end
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
end
|
data/lib/hobosupport/hash.rb
CHANGED
@@ -5,8 +5,8 @@ class Hash
|
|
5
5
|
each {|k,v| res[k] = v if (b.arity == 1 ? yield(v) : yield(k, v)) }
|
6
6
|
res
|
7
7
|
end
|
8
|
-
|
9
|
-
|
8
|
+
|
9
|
+
|
10
10
|
def map_hash(&b)
|
11
11
|
res = {}
|
12
12
|
each {|k,v| res[k] = b.arity == 1 ? yield(v) : yield(k, v) }
|
@@ -25,7 +25,7 @@ class Hash
|
|
25
25
|
end
|
26
26
|
[yes, no]
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
def recursive_update(hash)
|
30
30
|
hash.each_pair do |key, value|
|
31
31
|
current = self[key]
|
@@ -36,36 +36,36 @@ class Hash
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
def -(keys)
|
41
41
|
res = {}
|
42
42
|
each_pair {|k, v| res[k] = v unless k.in?(keys)}
|
43
43
|
res
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
def &(keys)
|
47
47
|
res = {}
|
48
48
|
keys.each {|k| res[k] = self[k] if has_key?(k)}
|
49
|
-
res
|
49
|
+
res
|
50
50
|
end
|
51
|
-
|
51
|
+
|
52
52
|
alias_method :| , :merge
|
53
|
-
|
53
|
+
|
54
54
|
def get(*args)
|
55
55
|
args.map {|a| self[a] }
|
56
56
|
end
|
57
|
-
|
57
|
+
|
58
58
|
def compact
|
59
59
|
res = {}
|
60
60
|
each { |k, v| res[k] = v unless v.nil? }
|
61
61
|
res
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
def compact!
|
65
65
|
keys.each { |k| delete(k) if self[k].nil? }
|
66
66
|
end
|
67
|
-
|
68
|
-
|
67
|
+
|
68
|
+
|
69
69
|
end
|
70
70
|
|
71
71
|
|
@@ -73,25 +73,25 @@ end
|
|
73
73
|
# versions of these
|
74
74
|
|
75
75
|
if defined? HashWithIndifferentAccess
|
76
|
-
|
76
|
+
|
77
77
|
class HashWithIndifferentAccess
|
78
|
-
|
78
|
+
|
79
79
|
def -(keys)
|
80
80
|
res = HashWithIndifferentAccess.new
|
81
81
|
keys = keys.map {|k| k.is_a?(Symbol) ? k.to_s : k }
|
82
82
|
each_pair { |k, v| res[k] = v unless k.in?(keys) }
|
83
83
|
res
|
84
84
|
end
|
85
|
-
|
85
|
+
|
86
86
|
def &(keys)
|
87
87
|
res = HashWithIndifferentAccess.new
|
88
88
|
keys.each do |k|
|
89
89
|
k = k.to_s if k.is_a?(Symbol)
|
90
90
|
res[k] = self[k] if has_key?(k)
|
91
91
|
end
|
92
|
-
res
|
92
|
+
res
|
93
93
|
end
|
94
|
-
|
94
|
+
|
95
95
|
def partition_hash(keys=nil)
|
96
96
|
keys = keys._?.map {|k| k.is_a?(Symbol) ? k.to_s : k }
|
97
97
|
yes = HashWithIndifferentAccess.new
|
@@ -105,7 +105,13 @@ if defined? HashWithIndifferentAccess
|
|
105
105
|
end
|
106
106
|
[yes, no]
|
107
107
|
end
|
108
|
-
|
108
|
+
|
109
109
|
end
|
110
110
|
|
111
111
|
end
|
112
|
+
|
113
|
+
if defined? ActiveSupport
|
114
|
+
class ActiveSupport::OrderedHash
|
115
|
+
alias each_pair each
|
116
|
+
end
|
117
|
+
end
|
data/lib/hobosupport/implies.rb
CHANGED
data/lib/hobosupport/metaid.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# .? calls a method if the reciever is not nil, returns nil
|
4
4
|
# otherwise. We have to write it ._?. in order to be valid Ruby
|
5
5
|
#
|
6
|
-
# .try. calls a mehod only if the recipient resonds to that method
|
6
|
+
# .try. calls a mehod only if the recipient resonds to that method
|
7
7
|
|
8
8
|
require 'delegate'
|
9
9
|
require 'singleton'
|
@@ -14,14 +14,14 @@ class Object
|
|
14
14
|
def _?()
|
15
15
|
self
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
def try
|
19
19
|
CallIfAvailable.new(self)
|
20
20
|
end
|
21
21
|
|
22
22
|
end
|
23
23
|
|
24
|
-
|
24
|
+
|
25
25
|
class NilClass
|
26
26
|
def _?()
|
27
27
|
SafeNil.instance
|
@@ -29,9 +29,9 @@ class NilClass
|
|
29
29
|
end
|
30
30
|
|
31
31
|
|
32
|
-
class SafeNil
|
32
|
+
class SafeNil
|
33
33
|
include Singleton
|
34
|
-
|
34
|
+
|
35
35
|
def method_missing(method, *args, &b)
|
36
36
|
return nil unless nil.respond_to? method
|
37
37
|
nil.send(method, *args, &b) rescue nil
|
@@ -39,10 +39,10 @@ class SafeNil
|
|
39
39
|
end
|
40
40
|
|
41
41
|
|
42
|
-
alias DelegateClass_without_safe_nil DelegateClass
|
42
|
+
alias DelegateClass_without_safe_nil DelegateClass
|
43
43
|
def DelegateClass(klass)
|
44
44
|
c = DelegateClass_without_safe_nil(klass)
|
45
|
-
c.class_eval do
|
45
|
+
c.class_eval do
|
46
46
|
def _?
|
47
47
|
self
|
48
48
|
end
|
@@ -52,15 +52,15 @@ end
|
|
52
52
|
|
53
53
|
|
54
54
|
class CallIfAvailable < BlankSlate
|
55
|
-
|
55
|
+
|
56
56
|
def initialize(target)
|
57
57
|
@target = target
|
58
58
|
end
|
59
|
-
|
59
|
+
|
60
60
|
def method_missing(name, *args, &b)
|
61
61
|
@target.send(name, *args, &b) if @target.respond_to?(name)
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
end
|
65
65
|
|
66
66
|
|
data/lib/hobosupport/module.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
class Module
|
2
|
-
|
2
|
+
|
3
3
|
private
|
4
|
-
|
4
|
+
|
5
5
|
# In a module definition you can include a call to
|
6
6
|
# included_in_class_callbacks(base) at the end of the
|
7
7
|
# self.included(base) callback. Any modules that your module includes
|
@@ -13,16 +13,16 @@ class Module
|
|
13
13
|
included_modules.each { |m| m.included_in_class(base) if m.respond_to?(:included_in_class) }
|
14
14
|
end
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
# Creates a class attribute reader that will delegate to the superclass
|
18
18
|
# if not defined on self
|
19
19
|
def inheriting_cattr_reader(*names)
|
20
20
|
names_with_defaults = (names.pop if names.last.is_a?(Hash)) || {}
|
21
|
-
|
21
|
+
|
22
22
|
names_with_defaults.each do |name, default|
|
23
23
|
instance_variable_set("@#{name}", default) unless instance_variable_get("@#{name}") != nil || superclass.respond_to?(name)
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
(names + names_with_defaults.keys).each do |name|
|
27
27
|
class_eval %{
|
28
28
|
def self.#{name}
|
@@ -35,14 +35,14 @@ class Module
|
|
35
35
|
}
|
36
36
|
end
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
# creates a #foo= and #foo? pair, with optional default values, e.g.
|
40
40
|
# bool_attr_accessor :happy => true
|
41
41
|
def bool_attr_accessor(*args)
|
42
42
|
options = (args.pop if args.last.is_a?(Hash)) || {}
|
43
|
-
|
43
|
+
|
44
44
|
(args + options.keys).each {|n| class_eval "def #{n}=(x); @#{n} = x; end" }
|
45
|
-
|
45
|
+
|
46
46
|
args.each {|n| class_eval "def #{n}?; @#{n}; end" }
|
47
47
|
|
48
48
|
options.keys.each do |n|
|
@@ -56,7 +56,7 @@ class Module
|
|
56
56
|
set_field_type(n => TrueClass) if respond_to?(:set_field_type)
|
57
57
|
end
|
58
58
|
end
|
59
|
-
|
59
|
+
|
60
60
|
def alias_class_method_chain(method, feature)
|
61
61
|
meta_eval do
|
62
62
|
alias_method_chain method, feature
|
@@ -69,7 +69,7 @@ end
|
|
69
69
|
# classy_module lets you extract code from classes into modules, but
|
70
70
|
# still write it the same way
|
71
71
|
module Kernel
|
72
|
-
|
72
|
+
|
73
73
|
def classy_module(&b)
|
74
74
|
m = Module.new
|
75
75
|
m.meta_def :included do |base|
|
@@ -77,5 +77,5 @@ module Kernel
|
|
77
77
|
end
|
78
78
|
m
|
79
79
|
end
|
80
|
-
|
80
|
+
|
81
81
|
end
|
data/test/hobosupport.rdoctest
CHANGED
@@ -6,7 +6,7 @@ HoboSupport is a mixed bag of core ruby extensions that have been extracted from
|
|
6
6
|
|
7
7
|
>> require 'hobosupport'
|
8
8
|
>> HoboSupport::VERSION
|
9
|
-
=> "0.
|
9
|
+
=> "0.7.5"
|
10
10
|
|
11
11
|
## Contents
|
12
12
|
|
@@ -29,15 +29,15 @@ Extended to allow multiple types to be checked in one go
|
|
29
29
|
=> true
|
30
30
|
>> 1.is_a?(String, Symbol)
|
31
31
|
=> false
|
32
|
-
|
32
|
+
|
33
33
|
Still works the old way
|
34
34
|
|
35
35
|
>> "foo".is_a?(String)
|
36
36
|
=> true
|
37
37
|
>> :foo.is_a?(String)
|
38
38
|
=> false
|
39
|
-
|
40
|
-
|
39
|
+
|
40
|
+
|
41
41
|
## Method call extensions
|
42
42
|
|
43
43
|
### `Object#_?`
|
@@ -48,7 +48,7 @@ We have the "." operator to call methods on objects. These extensions introduce
|
|
48
48
|
=> 3
|
49
49
|
>> nil._?.length
|
50
50
|
=> nil
|
51
|
-
|
51
|
+
|
52
52
|
|
53
53
|
### `Object#try`
|
54
54
|
|
@@ -1,20 +1,18 @@
|
|
1
1
|
# HoboSupport - Eumerable extensions
|
2
2
|
|
3
3
|
>> require 'hobosupport'
|
4
|
-
>> HoboSupport::VERSION
|
5
|
-
=> "0.1"
|
6
4
|
|
7
|
-
## `Enumerable#
|
5
|
+
## `Enumerable#map_and_find`
|
8
6
|
|
9
|
-
* `enum.
|
7
|
+
* `enum.map_and_find(not_found) { |element| block}`
|
10
8
|
|
11
9
|
Iterates through an enumerable passing each element in turn to the block. Returns the first true value returned by the block, or `not_found` if the block never returns a true value.
|
12
10
|
|
13
11
|
E.g. The length of the first word that starts with a capital letter
|
14
12
|
|
15
|
-
>> %w(my name is Fred).
|
13
|
+
>> %w(my name is Fred).map_and_find { |s| s.length if s =~ /^[A-Z]/ }
|
16
14
|
=> 4
|
17
|
-
|
15
|
+
|
18
16
|
## `Enumerable#map_with_index`
|
19
17
|
|
20
18
|
* `enum.map_with_index { |element, index| block }`
|
@@ -23,7 +21,7 @@ Just like #map but the block gets the element and the index.
|
|
23
21
|
|
24
22
|
>> %w(some short words).map_with_index { |s, i| s * i }
|
25
23
|
=> ["", "short", "wordswords"]
|
26
|
-
|
24
|
+
|
27
25
|
## `Enumerable#build_hash`
|
28
26
|
|
29
27
|
* `enum.build_hash { |element| block }`
|
@@ -32,7 +30,7 @@ The block is passed each element in turn and should return a key/value pair. If
|
|
32
30
|
|
33
31
|
>> %w(some short words).build_hash { |s| [s, s.length] unless s == "short" }
|
34
32
|
=> {"some"=>4, "words"=>5}
|
35
|
-
|
33
|
+
|
36
34
|
|
37
35
|
## `Enumerable#map_hash`
|
38
36
|
|
@@ -49,29 +47,29 @@ Shorthand for `enum[1..-1]`
|
|
49
47
|
|
50
48
|
>> %w(some short words).rest
|
51
49
|
=> ["short", "words"]
|
52
|
-
|
53
|
-
|
50
|
+
|
51
|
+
|
54
52
|
## `Enumerable#*`
|
55
53
|
|
56
54
|
Shorthand for `map` when you need to map a single method call on the elements.
|
57
55
|
|
58
56
|
>> %w(some short words).*.length
|
59
57
|
=> [4, 5, 5]
|
60
|
-
|
58
|
+
|
61
59
|
## `Enumerable#where`
|
62
60
|
|
63
61
|
Shorthand for `select` when you need to select on a single method call.
|
64
62
|
|
65
63
|
>> %w(some short words).where.include?("r")
|
66
64
|
=> ["short", "words"]
|
67
|
-
|
65
|
+
|
68
66
|
## `Enumerable#where_not`
|
69
67
|
|
70
68
|
Shorthand for `reject` when you need to reject on a single method call.
|
71
69
|
|
72
70
|
>> %w(some short words).where_not.include?("r")
|
73
71
|
=> ["some"]
|
74
|
-
|
72
|
+
|
75
73
|
## `Enumerable#drop_while`
|
76
74
|
|
77
75
|
* `enum.drop_while { |element| block }`
|
@@ -80,14 +78,14 @@ Passes each element in turn to the block until the block returns false. Returns
|
|
80
78
|
|
81
79
|
>> %w(this is a nice example).drop_while { |s| s.length > 1 }
|
82
80
|
=> ["a", "nice", "example"]
|
83
|
-
|
81
|
+
|
84
82
|
There is also a destructive version for arrays
|
85
83
|
|
86
84
|
>> a = %w(this is a nice example)
|
87
85
|
>> a.drop_while! { |s| s.length > 1 }
|
88
86
|
>> a
|
89
87
|
=> ["a", "nice", "example"]
|
90
|
-
|
88
|
+
|
91
89
|
|
92
90
|
## `Enumerable#take_while`
|
93
91
|
|
@@ -1,9 +1,7 @@
|
|
1
1
|
# HoboSupport - Hash extensions
|
2
2
|
|
3
3
|
>> require 'hobosupport'
|
4
|
-
|
5
|
-
=> "0.1"
|
6
|
-
|
4
|
+
|
7
5
|
## `Hash#select_hash`
|
8
6
|
|
9
7
|
* `hash.select_hash { |key, value| block } => hash`
|
@@ -13,12 +11,12 @@ This is the Hash version of `Enumerable#select`. i.e. a way to create a new hash
|
|
13
11
|
|
14
12
|
>> {1=>2, 3=>4, 6=>5}.select_hash { |key, value| key < value }
|
15
13
|
=> {1=>2, 3=>4}
|
16
|
-
|
14
|
+
|
17
15
|
You can also give a block that takes one argument, in which case the block is given the value only
|
18
16
|
|
19
17
|
>> {1=>2, 3=>4, 6=>5}.select_hash { |value| value != 2 }
|
20
18
|
=> {3=>4, 6=>5}
|
21
|
-
|
19
|
+
|
22
20
|
|
23
21
|
## `Hash#map_hash`
|
24
22
|
|
@@ -29,13 +27,13 @@ Applies a function to each *value* in a Hash, resulting in a new hash with the s
|
|
29
27
|
|
30
28
|
>> {1=>2, 3=>4, 6=>5}.map_hash { |key, value| key < value }
|
31
29
|
=> {1=>true, 3=>true, 6=>false}
|
32
|
-
|
30
|
+
|
33
31
|
You can also give a block which takes one argument, in which case only the value is passed in
|
34
32
|
|
35
33
|
>> {1=>2, 3=>4, 6=>5}.map_hash { |value| value * 100 }
|
36
34
|
=> {1=>200, 3=>400, 6=>500 }
|
37
35
|
|
38
|
-
|
36
|
+
|
39
37
|
## `Hash#partition_hash`
|
40
38
|
|
41
39
|
* `hash.partition_hash(keys) => [hash1, hash2]`
|
@@ -45,12 +43,12 @@ Returns an array of two hashes, the first with all the key/value pairs where the
|
|
45
43
|
|
46
44
|
>> {1=>2, 3=>4, 6=>5}.partition_hash([1, 3])
|
47
45
|
=> [{1=>2, 3=>4}, {6=>5}]
|
48
|
-
|
46
|
+
|
49
47
|
When passed a block, each pair is passed to the block in turn. The result is two hashes, the first containing those pairs for which the block returned true, the second with the remaining pairs
|
50
48
|
|
51
49
|
>> {1=>2, 3=>4, 6=>5}.partition_hash { |key, value| key < value }
|
52
50
|
=> [{1=>2, 3=>4}, {6=>5}]
|
53
|
-
|
51
|
+
|
54
52
|
## `Hash.recursive_update`
|
55
53
|
|
56
54
|
* `hash.recursive_update(hash2)`
|
@@ -71,7 +69,7 @@ Returns a new hash, the left-hand-side hash with all pairs removed where the key
|
|
71
69
|
|
72
70
|
>> {1=>2, 3=>4, 6=>5} - [1, 3]
|
73
71
|
=> {6 => 5}
|
74
|
-
|
72
|
+
|
75
73
|
## `Hash#&`
|
76
74
|
|
77
75
|
* `hash & array => array`
|
@@ -80,7 +78,7 @@ Returns a new array, the left hand side hash restricted to pairs where the key i
|
|
80
78
|
|
81
79
|
>> {1=>2, 3=>4, 6=>5} & [1, 3]
|
82
80
|
=> {1=>2, 3=>4}
|
83
|
-
|
81
|
+
|
84
82
|
## `Hash#|`
|
85
83
|
|
86
84
|
* `hash | hash => hash`
|
@@ -89,8 +87,8 @@ An alias for merge
|
|
89
87
|
|
90
88
|
>> {1 => 2} | {1 => 3, 2 => 4}
|
91
89
|
=> {1 => 3, 2 => 4}
|
92
|
-
|
93
|
-
|
90
|
+
|
91
|
+
|
94
92
|
## `Hash#get`
|
95
93
|
|
96
94
|
* `hash.get(*args) => hash`
|
@@ -99,7 +97,7 @@ Returns an array of values for the given keys. Useful for extracting a few optio
|
|
99
97
|
|
100
98
|
>> {1=>2, 3=>4, 6=>5}.get(1, 3)
|
101
99
|
=> [2, 4]
|
102
|
-
|
100
|
+
|
103
101
|
## `Hash#compact`
|
104
102
|
|
105
103
|
* `hash.compact => hash`
|
@@ -108,7 +106,7 @@ Returns a hash with the same items as the receiver except those where the value
|
|
108
106
|
|
109
107
|
>> {1=>'a', 2=>nil, 3=>'b'}.compact
|
110
108
|
=> {1=>'a', 3=>'b'}
|
111
|
-
|
109
|
+
|
112
110
|
## `Hash#compact`
|
113
111
|
|
114
112
|
* `hash.compact!`
|
@@ -119,6 +117,6 @@ Removes every pair from the hash where the value is nil
|
|
119
117
|
>> h.compact!
|
120
118
|
>> h
|
121
119
|
=> {1=>'a', 3=>'b'}
|
122
|
-
|
120
|
+
|
123
121
|
|
124
122
|
|
@@ -1,8 +1,6 @@
|
|
1
1
|
# HoboSupport - implies
|
2
2
|
|
3
3
|
>> require 'hobosupport'
|
4
|
-
>> HoboSupport::VERSION
|
5
|
-
=> "0.1"
|
6
4
|
|
7
5
|
The implies operator comes from Eiffel. Often comes in handy in Hobo's model-permission methods.
|
8
6
|
|
@@ -10,12 +8,12 @@ The implies operator comes from Eiffel. Often comes in handy in Hobo's model-per
|
|
10
8
|
|
11
9
|
>> false.implies true
|
12
10
|
=> true
|
13
|
-
|
11
|
+
|
14
12
|
>> false.implies false
|
15
13
|
=> true
|
16
|
-
|
14
|
+
|
17
15
|
>> true.implies true
|
18
16
|
=> true
|
19
|
-
|
17
|
+
|
20
18
|
>> true.implies false
|
21
|
-
=> false
|
19
|
+
=> false
|
@@ -1,8 +1,6 @@
|
|
1
1
|
# HoboSupport - Metaid
|
2
2
|
|
3
3
|
>> require 'hobosupport'
|
4
|
-
>> HoboSupport::VERSION
|
5
|
-
=> "0.1"
|
6
4
|
|
7
5
|
Why the Luck Stiff's essential meta-programming additions to Object. These are probably distributed elsewhere, but they're small enough to throw them in to HoboSupport and remove an external dependency.
|
8
6
|
|
@@ -50,11 +48,11 @@ And with a block
|
|
50
48
|
>> File.metaclass_eval { def b4(path); basename(path); end }
|
51
49
|
>> File.b4 "a/b"
|
52
50
|
=> "b"
|
53
|
-
|
54
|
-
|
51
|
+
|
52
|
+
|
55
53
|
## `Object#meta_def`
|
56
54
|
|
57
55
|
>> String.meta_def(:backwards_new) { |s| s.reverse }
|
58
56
|
>> String.backwards_new "strange"
|
59
57
|
=> "egnarts"
|
60
|
-
|
58
|
+
|
@@ -1,8 +1,6 @@
|
|
1
1
|
# HoboSupport - Methodphitamine
|
2
2
|
|
3
3
|
>> require 'hobosupport'
|
4
|
-
>> HoboSupport::VERSION
|
5
|
-
=> "0.1"
|
6
4
|
|
7
5
|
## `Kernel#it` and `Kernel#its`
|
8
6
|
|
@@ -14,6 +12,6 @@ A nice hack from Jay Phillips, christened "Methodphitamine". The low-down is in
|
|
14
12
|
=> [2, 4, 6, 8, 10]
|
15
13
|
>> %w(a few short words).map &its.length
|
16
14
|
=> [1, 3, 5, 5]
|
17
|
-
|
15
|
+
|
18
16
|
Note that `it` and `its` are identical. They just read better in different contexts. Note that methodphitamine is also released directly by Jay (simply `gem install methodphitamine`) but it's small enough that it seemed easier to add it to HoboSupport and avoid an extra dependency. Thanks to Jay.
|
19
17
|
|
@@ -1,8 +1,6 @@
|
|
1
1
|
# HoboSupport - Module extensions
|
2
2
|
|
3
3
|
>> require 'hobosupport'
|
4
|
-
>> HoboSupport::VERSION
|
5
|
-
=> "0.1"
|
6
4
|
|
7
5
|
## `Module#included_in_class_callbacks`
|
8
6
|
|
@@ -23,25 +21,25 @@ When a module is included in a class, it gets a callback on the `included` metho
|
|
23
21
|
end
|
24
22
|
end
|
25
23
|
end
|
26
|
-
|
24
|
+
|
27
25
|
module M1
|
28
26
|
def self.included(base)
|
29
27
|
included_in_class_callbacks(base)
|
30
28
|
end
|
31
29
|
include M2
|
32
30
|
end
|
33
|
-
|
31
|
+
|
34
32
|
class C
|
35
33
|
def self.name
|
36
34
|
"my name is C"
|
37
35
|
end
|
38
36
|
include M1
|
39
37
|
end
|
40
|
-
|
38
|
+
|
41
39
|
C.name
|
42
40
|
=> "MY NAME IS C"
|
43
|
-
|
44
|
-
|
41
|
+
|
42
|
+
|
45
43
|
## `Module#interiting_cattr_reader`
|
46
44
|
|
47
45
|
Declares a reader for an instance variable on the class. The attribute is looked up on the superclass if not defined on the receiving class. In other words, the superclass defines a default that subclasses can override. The declaration can also give a default, as shown here.
|
@@ -50,25 +48,25 @@ Declares a reader for an instance variable on the class. The attribute is looked
|
|
50
48
|
class A
|
51
49
|
inheriting_cattr_reader :nickname => "Andy"
|
52
50
|
end
|
53
|
-
|
51
|
+
|
54
52
|
class B < A; end
|
55
|
-
|
53
|
+
|
56
54
|
`B` has the same nickname as its superclass `A`
|
57
|
-
|
55
|
+
|
58
56
|
>> A.nickname
|
59
57
|
=> "Andy"
|
60
58
|
>> B.nickname
|
61
59
|
=> "Andy"
|
62
|
-
|
60
|
+
|
63
61
|
Now we change the nickname of `B`. `A` retains it's existing nickname.
|
64
|
-
|
62
|
+
|
65
63
|
>> class B; @nickname = "Bob"; end
|
66
64
|
>> B.nickname
|
67
65
|
=> "Bob"
|
68
66
|
>> A.nickname
|
69
67
|
=> "Andy"
|
70
|
-
|
71
|
-
|
68
|
+
|
69
|
+
|
72
70
|
## `Kernel#classy_module`
|
73
71
|
|
74
72
|
In Ruby we use modules to factor out features that are shared by more than one class. By including the module, a class gets the module's features, just as if they were defined inside the class. This mechanism is very simple if the shared features are all instance methods, but starts to get complicated when we want to share class-level features. For example, to create a module that adds class-methods to the including class, Ruby programmers often use the ClassMethods sub-module idiom:
|
@@ -78,32 +76,32 @@ In Ruby we use modules to factor out features that are shared by more than one c
|
|
78
76
|
def self.included(base)
|
79
77
|
base.send(:extend, ClassMethods)
|
80
78
|
end
|
81
|
-
|
79
|
+
|
82
80
|
module ClassMethods
|
83
81
|
def foo; 123; end
|
84
82
|
end
|
85
83
|
end
|
86
|
-
|
84
|
+
|
87
85
|
class C; include M; end
|
88
|
-
|
86
|
+
|
89
87
|
>> C.foo
|
90
88
|
=> 123
|
91
|
-
|
89
|
+
|
92
90
|
It's a shame that such a basic capability isn't more declarative.
|
93
|
-
|
91
|
+
|
94
92
|
`classy_module` provides a mechanism for creating a module that, when included, will `class_eval` it's entire body (the block passed to `classy_module`). This means we can write shared class features exactly as we would write them if they were inside the class:
|
95
93
|
|
96
|
-
>>
|
94
|
+
>>
|
97
95
|
MyClassyModule = classy_module do
|
98
|
-
|
96
|
+
|
99
97
|
def self.foo; 123; end
|
100
|
-
|
98
|
+
|
101
99
|
end
|
102
|
-
|
100
|
+
|
103
101
|
>> MyClassyModule.class
|
104
102
|
=> Module
|
105
103
|
>> class C2; include MyClassyModule; end
|
106
104
|
>> C2.foo
|
107
105
|
=> 123
|
108
|
-
|
109
|
-
|
106
|
+
|
107
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hobosupport
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: "0.8"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Locke
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-
|
12
|
+
date: 2008-09-03 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -51,6 +51,7 @@ files:
|
|
51
51
|
- lib/hobosupport/methodphitamine.rb
|
52
52
|
- lib/hobosupport/module.rb
|
53
53
|
- lib/hobosupport.rb
|
54
|
+
- Manifest
|
54
55
|
- Manifest.txt
|
55
56
|
- README.txt
|
56
57
|
- test/hobosupport/enumerable.rdoctest
|
@@ -60,7 +61,6 @@ files:
|
|
60
61
|
- test/hobosupport/methodphitamine.rdoctest
|
61
62
|
- test/hobosupport/module.rdoctest
|
62
63
|
- test/hobosupport.rdoctest
|
63
|
-
- Manifest
|
64
64
|
- hobosupport.gemspec
|
65
65
|
has_rdoc: true
|
66
66
|
homepage: http://hobocentral.net/hobosupport
|
@@ -89,7 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
89
89
|
requirements: []
|
90
90
|
|
91
91
|
rubyforge_project: hobo
|
92
|
-
rubygems_version: 1.0
|
92
|
+
rubygems_version: 1.2.0
|
93
93
|
signing_key:
|
94
94
|
specification_version: 2
|
95
95
|
summary: Core Ruby extensions from the Hobo project
|