hobo_support 1.3.0.RC

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.
@@ -0,0 +1,33 @@
1
+ # From: http://jicksta.com/articles/2007/08/04/the-methodphitamine
2
+
3
+ require 'blankslate'
4
+
5
+ module Kernel
6
+
7
+ def it() It.new end
8
+ alias its it
9
+
10
+ end
11
+
12
+ class It
13
+
14
+ instance_methods.reject { |m| m =~ /^__/ || m.to_s == 'object_id' }.each { |m| undef_method m }
15
+
16
+ def initialize
17
+ @methods = []
18
+ end
19
+
20
+ def method_missing(*args, &block)
21
+ @methods << [args, block] unless args == [:respond_to?, :to_proc]
22
+ self
23
+ end
24
+
25
+ def to_proc
26
+ lambda do |obj|
27
+ @methods.inject(obj) do |current,(args,block)|
28
+ current.send(*args, &block)
29
+ end
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,102 @@
1
+ class Module
2
+
3
+ private
4
+
5
+ # In a module definition you can include a call to
6
+ # included_in_class_callbacks(base) at the end of the
7
+ # self.included(base) callback. Any modules that your module includes
8
+ # will receive an included_in_class callback when your module is
9
+ # included in a class. Useful if the sub-module wants to do something
10
+ # like alias_method_chain on the class.
11
+ def included_in_class_callbacks(base)
12
+ if base.is_a?(Class)
13
+ included_modules.each { |m| m.try.included_in_class(base) }
14
+ end
15
+ end
16
+
17
+ # Creates a class attribute reader that will delegate to the superclass
18
+ # if not defined on self. Default values can be a Proc object that takes the class as a parameter.
19
+ def inheriting_cattr_reader(*names)
20
+ names_with_defaults = (names.pop if names.last.is_a?(Hash)) || {}
21
+
22
+ (names + names_with_defaults.keys).each do |name|
23
+ ivar_name = "@#{name}"
24
+ block = names_with_defaults[name]
25
+ self.send(self.class == Module ? :define_method : :meta_def, name) do
26
+ if instance_variable_defined? ivar_name
27
+ instance_variable_get(ivar_name)
28
+ else
29
+ superclass.respond_to?(name) && superclass.send(name) ||
30
+ block && begin
31
+ result = block.is_a?(Proc) ? block.call(self) : block
32
+ instance_variable_set(ivar_name, result) if result
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ def inheriting_cattr_accessor(*names)
40
+ names_with_defaults = (names.pop if names.last.is_a?(Hash)) || {}
41
+
42
+ names_with_defaults.keys.each do |name|
43
+ attr_writer name
44
+ inheriting_cattr_reader names_with_defaults.slice(name)
45
+ end
46
+ names.each do |name|
47
+ attr_writer name
48
+ inheriting_cattr_reader name
49
+ end
50
+ end
51
+
52
+
53
+ # creates a #foo= and #foo? pair, with optional default values, e.g.
54
+ # bool_attr_accessor :happy => true
55
+ def bool_attr_accessor(*args)
56
+ options = (args.pop if args.last.is_a?(Hash)) || {}
57
+
58
+ (args + options.keys).each {|n| class_eval "def #{n}=(x); @#{n} = x; end" }
59
+
60
+ args.each {|n| class_eval "def #{n}?; @#{n}; end" }
61
+
62
+ options.keys.each do |n|
63
+ class_eval %(def #{n}?
64
+ if !defined? @#{n}
65
+ @#{n} = #{options[n] ? 'true' : 'false'}
66
+ else
67
+ @#{n}
68
+ end
69
+ end)
70
+ set_field_type(n => TrueClass) if respond_to?(:set_field_type)
71
+ end
72
+ end
73
+
74
+ def alias_class_method_chain(method, feature)
75
+ meta_eval do
76
+ alias_method_chain method, feature
77
+ end
78
+ end
79
+
80
+ end
81
+
82
+
83
+ # classy_module lets you extract code from classes into modules, but
84
+ # still write it the same way
85
+ module Kernel
86
+
87
+ def classy_module(mod=Module.new, &b)
88
+ mod.meta_def :included do |base|
89
+ base.class_eval &b
90
+ end
91
+ mod
92
+ end
93
+
94
+ end
95
+
96
+ class Object
97
+
98
+ def is_one_of?(*args)
99
+ args.any? {|a| is_a?(a) }
100
+ end
101
+
102
+ end
@@ -0,0 +1,34 @@
1
+ class String
2
+
3
+ def remove(string_or_rx)
4
+ sub(string_or_rx, '')
5
+ end
6
+
7
+ def remove!(string_or_rx)
8
+ sub!(string_or_rx, '')
9
+ end
10
+
11
+ def remove_all(string_or_rx)
12
+ gsub(string_or_rx, '')
13
+ end
14
+
15
+ def remove_all!(string_or_rx)
16
+ gsub!(string_or_rx, '')
17
+ end
18
+
19
+ # Return the constant that this string refers to, or nil if ActiveSupport cannot load such a
20
+ # constant. This is much safer than `rescue NameError`, as that will mask genuine NameErrors
21
+ # that have been made in the code being loaded (#safe_constantize will not)
22
+ def safe_constantize
23
+ Object.class_eval self
24
+ rescue NameError => e
25
+ if e.missing_name != self
26
+ # oops - some other name error
27
+ raise
28
+ else
29
+ nil
30
+ end
31
+ end
32
+
33
+
34
+ end
@@ -0,0 +1,11 @@
1
+ require 'active_support/core_ext/string/output_safety'
2
+ class Array
3
+ # it always returns an html_safe? string preserving the html_safe?
4
+ # items and separator, excaping the rest
5
+ def safe_join(sep=$,)
6
+ map {|i| ERB::Util.html_escape(i)}.join(ERB::Util.html_escape(sep)).html_safe
7
+ end
8
+ end
9
+
10
+
11
+
@@ -0,0 +1,75 @@
1
+ # HoboSupport
2
+
3
+ HoboSupport is a mixed bag of core ruby extensions that have been extracted from the [Hobo][] project
4
+
5
+ [Hobo]: http://hobocentral.net
6
+
7
+ doctest_require: '../lib/hobo_support'
8
+ {.hidden}
9
+
10
+
11
+ ## Contents
12
+
13
+ * [Enumerable](/manual/hobo_support/enumerable)
14
+ * [Hash](/manual/hobo_support/hash)
15
+ * [Implies](/manual/hobo_support/implies)
16
+ * [Metaid](/manual/hobo_support/metaid)
17
+ * [Methodphitamine](/manual/hobo_support/methodphitamine)
18
+ * [Module](/manual/hobo_support/module)
19
+
20
+ ## Object extensions
21
+
22
+ ### `Object#is_one_of?`
23
+
24
+ Like `is_a?` but multiple types to be checked in one go
25
+
26
+ >> "foo".is_one_of?(String, Symbol)
27
+ => true
28
+ >> :foo.is_one_of?(String, Symbol)
29
+ => true
30
+ >> 1.is_one_of?(String, Symbol)
31
+ => false
32
+
33
+ ## Method call extensions
34
+
35
+ We have the "." operator to call methods on objects. These extensions introduce two "special dots".
36
+
37
+ ### `Object#_?`
38
+
39
+ "`._?.`" only calls the method if the receiver is not `nil`. Otherwise it returns nil. So `x._?.method(*args)` is equivalent to `(nil == x ? nil : x.method(*args))`.
40
+
41
+ >> "foo"._?.length
42
+ => 3
43
+ >> nil._?.length
44
+ => nil
45
+
46
+ When the receiver is nil, any method with any arguments will return nil. You can use Ruby's || idiom to provide a different value when nil.
47
+
48
+ >> expires = nil
49
+ >> expires._?.to_s( :default ) || "never"
50
+ => "never"
51
+
52
+ Note that `_?` should *always* be followed by a method call. It is not intended to store the intermediate result. Don't do this!
53
+
54
+ intermediate = nil._?
55
+
56
+ ### `Object#try`
57
+
58
+ "`.try`" only calls the method if the receiver responds to that method. Otherwise it returns nil. So `x.try.method(*args)` is equivalent to `(x.respond_to?(:method) ? x.method(*args) : nil)`.
59
+
60
+ >> "foo".try.reverse
61
+ => "oof"
62
+ >> :foo.try.reverse
63
+ => nil
64
+
65
+ ### What's the difference?
66
+
67
+ Use `_?` when you want to call a method but you know the receiver may be nil.
68
+ Use `try` when you want to call a method but you know the receiver may not respond to it. For instance, you
69
+ may use `try` to call a Rails 2.3 function that doesn't exist on Rails
70
+ 2.2. Note that nil responds to some functions that may surprise you.
71
+
72
+ >> nil.try.to_i
73
+ => 0
74
+ >> nil._?.to_i
75
+ => nil
@@ -0,0 +1,18 @@
1
+ # HoboSupport - Chronic extensions
2
+
3
+ doctest_require: '../../lib/hobo_support'
4
+ {.hidden}
5
+
6
+ ## `Chronic.parse`
7
+
8
+ Chronic.parse can't parse 'M/D/Y H:S', so convert it to 'M/D/Y @ H:S'.
9
+
10
+ >> Chronic.parse('1/1/2008 1:00') == Chronic.parse('1/1/2008 @ 1:00')
11
+
12
+ => true
13
+
14
+ Chronic.parse takes additional options (see Chronic.parse).
15
+
16
+ >> Chronic.parse('today', :guess => false).instance_of? Chronic::Span
17
+
18
+ => true
@@ -0,0 +1,130 @@
1
+ # HoboSupport - Eumerable extensions
2
+
3
+ doctest_require: '../../lib/hobo_support'
4
+
5
+ ## `Enumerable#map_and_find`
6
+
7
+ * `enum.map_and_find(not_found) { |element| block}`
8
+
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.
10
+
11
+ E.g. The length of the first word that starts with a capital letter
12
+
13
+ >> %w(my name is Fred).map_and_find { |s| s.length if s =~ /^[A-Z]/ }
14
+ => 4
15
+
16
+ ## `Enumerable#map_with_index`
17
+
18
+ * `enum.map_with_index { |element, index| block }`
19
+
20
+ Just like #map but the block gets the element and the index.
21
+
22
+ >> %w(some short words).map_with_index { |s, i| s * i }
23
+ => ["", "short", "wordswords"]
24
+
25
+ ## `Enumerable#build_hash`
26
+
27
+ * `enum.build_hash { |element| block }`
28
+
29
+ The block is passed each element in turn and should return a key/value pair. If the block returns nil, nothing is added to the hash.
30
+
31
+ >> %w(some short words).build_hash { |s| [s, s.length] unless s == "short" }
32
+ => {"some"=>4, "words"=>5}
33
+
34
+
35
+ ## `Enumerable#map_hash`
36
+
37
+ * `enum.map_hash { |element| block }`
38
+
39
+ Each element is passed to the block. Returns a hash where the keys are the elements from the enumerable, and the values are those returned by the block for the given key.
40
+
41
+ >> %w(some short words).map_hash { |s| s.length }
42
+ => {"some"=>4, "short"=>5, "words"=>5}
43
+
44
+ ## `Enumerable#rest`
45
+
46
+ Shorthand for `enum[1..-1]`
47
+
48
+ >> %w(some short words).rest
49
+ => ["short", "words"]
50
+
51
+
52
+ ## `Enumerable#*`
53
+
54
+ Shorthand for `map` when you need to map a single method call on the elements.
55
+
56
+ >> %w(some short words).*.length
57
+ => [4, 5, 5]
58
+
59
+ ## `Enumerable#where`
60
+
61
+ Shorthand for `select` when you need to select on a single method call.
62
+
63
+ >> %w(some short words).where.include?("r")
64
+ => ["short", "words"]
65
+
66
+ ## `Enumerable#where_not`
67
+
68
+ Shorthand for `reject` when you need to reject on a single method call.
69
+
70
+ >> %w(some short words).where_not.include?("r")
71
+ => ["some"]
72
+
73
+ ## `Enumerable#drop_while`
74
+
75
+ * `enum.drop_while { |element| block }`
76
+
77
+ Passes each element in turn to the block until the block returns false. Returns the remaining elements in a new array.
78
+
79
+ >> %w(this is a nice example).drop_while { |s| s.length > 1 }
80
+ => ["a", "nice", "example"]
81
+
82
+ There is also a destructive version for arrays
83
+
84
+ >> a = %w(this is a nice example)
85
+ >> a.drop_while! { |s| s.length > 1 }
86
+ >> a
87
+ => ["a", "nice", "example"]
88
+
89
+
90
+ ## `Enumerable#take_while`
91
+
92
+ * `enum.take_while { |element| block }`
93
+
94
+ Passes each element in turn to the block until the block returns false. Returns a new with the elements for which the block returned true
95
+
96
+ >> %w(this is a nice example).take_while { |s| s.length > 1 }
97
+ => ["this", "is"]
98
+
99
+
100
+ ## `Object#in?`
101
+
102
+ * `obj.in?(enum)`
103
+
104
+ Shorthand for `enum.include?(obj)`
105
+
106
+ >> 3.in?(0..10)
107
+ => true
108
+ >> 300.in?(0..10)
109
+ => false
110
+
111
+ `in?` treats nil as an empty enumeration:
112
+
113
+ >> 3.in?(nil)
114
+ => false
115
+
116
+ ## `Object#not_in?`
117
+
118
+ * `obj.not_in?(enum)`
119
+
120
+ Negation of `in?`
121
+
122
+ >> 3.not_in?(0..10)
123
+ => false
124
+ >> 300.not_in?(0..10)
125
+ => true
126
+
127
+ `not_in?` treats nil as an empty enumeration:
128
+
129
+ >> 3.not_in?(nil)
130
+ => true
@@ -0,0 +1,123 @@
1
+ # HoboSupport - Hash extensions
2
+
3
+ doctest_require: '../../lib/hobo_support'
4
+ {.hidden}
5
+
6
+ ## `Hash#select_hash`
7
+
8
+ * `hash.select_hash { |key, value| block } => hash`
9
+ * `hash.select_hash { |value| block } => hash`
10
+
11
+ This is the Hash version of `Enumerable#select`. i.e. a way to create a new hash with only some of the items still present. The block is passed each key value pair. The new hash only contains items for which the block returned true.
12
+
13
+ >> {1=>2, 3=>4, 6=>5}.select_hash { |key, value| key < value }
14
+ => {1=>2, 3=>4}
15
+
16
+ You can also give a block that takes one argument, in which case the block is given the value only
17
+
18
+ >> {1=>2, 3=>4, 6=>5}.select_hash { |value| value != 2 }
19
+ => {3=>4, 6=>5}
20
+
21
+
22
+ ## `Hash#map_hash`
23
+
24
+ * `hash.map_hash { |key, value| block } => hash`
25
+ * `hash.map_hash { |value| block } => hash`
26
+
27
+ Applies a function to each *value* in a Hash, resulting in a new hash with the same keys but new values. The block is passed each key, value pair and should return the new value
28
+
29
+ >> {1=>2, 3=>4, 6=>5}.map_hash { |key, value| key < value }
30
+ => {1=>true, 3=>true, 6=>false}
31
+
32
+ You can also give a block which takes one argument, in which case only the value is passed in
33
+
34
+ >> {1=>2, 3=>4, 6=>5}.map_hash { |value| value * 100 }
35
+ => {1=>200, 3=>400, 6=>500 }
36
+
37
+
38
+ ## `Hash#partition_hash`
39
+
40
+ * `hash.partition_hash(keys) => [hash1, hash2]`
41
+ * `hash.partition_hash { |key, value| block } => hash`
42
+
43
+ Returns an array of two hashes, the first with all the key/value pairs where the key was in passed Enumerable, the second with the remaining key/value pairs
44
+
45
+ >> {1=>2, 3=>4, 6=>5}.partition_hash([1, 3])
46
+ => [{1=>2, 3=>4}, {6=>5}]
47
+
48
+ 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
49
+
50
+ >> {1=>2, 3=>4, 6=>5}.partition_hash { |key, value| key < value }
51
+ => [{1=>2, 3=>4}, {6=>5}]
52
+
53
+ ## `Hash.recursive_update`
54
+
55
+ * `hash.recursive_update(hash2)`
56
+
57
+ Like `#update` but where a sub-hash would overwrite another sub-hash, they are instead also merged, recursively
58
+
59
+ >> h = { :a => 1, :b => { :x => 10 } }
60
+ >> h.recursive_update({ :c => 3, :b => { :y => 20 } })
61
+ >> h
62
+ => { :a => 1, :b => { :x => 10, :y => 20}, :c => 3 }
63
+
64
+
65
+ ## `Hash#-`
66
+
67
+ * `hash - array => hash`
68
+
69
+ Returns a new hash, the left-hand-side hash with all pairs removed where the key is present in the right-hand-side array.
70
+
71
+ >> {1=>2, 3=>4, 6=>5} - [1, 3]
72
+ => {6 => 5}
73
+
74
+ ## `Hash#&`
75
+
76
+ * `hash & array => array`
77
+
78
+ Returns a new array, the left hand side hash restricted to pairs where the key is present in the right-hand-side array
79
+
80
+ >> {1=>2, 3=>4, 6=>5} & [1, 3]
81
+ => {1=>2, 3=>4}
82
+
83
+ ## `Hash#|`
84
+
85
+ * `hash | hash => hash`
86
+
87
+ An alias for merge
88
+
89
+ >> {1 => 2} | {1 => 3, 2 => 4}
90
+ => {1 => 3, 2 => 4}
91
+
92
+
93
+ ## `Hash#get`
94
+
95
+ * `hash.get(*args) => hash`
96
+
97
+ Returns an array of values for the given keys. Useful for extracting a few options into local variables.
98
+
99
+ >> {1=>2, 3=>4, 6=>5}.get(1, 3)
100
+ => [2, 4]
101
+
102
+ ## `Hash#compact`
103
+
104
+ * `hash.compact => hash`
105
+
106
+ Returns a hash with the same items as the receiver except those where the value is nil
107
+
108
+ >> {1=>'a', 2=>nil, 3=>'b'}.compact
109
+ => {1=>'a', 3=>'b'}
110
+
111
+ ## `Hash#compact`
112
+
113
+ * `hash.compact!`
114
+
115
+ Removes every pair from the hash where the value is nil
116
+
117
+ >> h = {1=>'a', 2=>nil, 3=>'b'}
118
+ >> h.compact!
119
+ >> h
120
+ => {1=>'a', 3=>'b'}
121
+
122
+
123
+