hobosupport 0.1 → 0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/hobosupport/enumerable.rb +2 -2
- data/lib/hobosupport/hash.rb +11 -0
- data/lib/hobosupport/methodcall.rb +6 -1
- data/lib/hobosupport/methodphitamine.rb +2 -0
- data/lib/hobosupport/module.rb +19 -5
- data/lib/hobosupport.rb +3 -13
- data/test/hobosupport/enumerable.rdoctest +10 -0
- data/test/hobosupport/hash.rdoctest +21 -0
- data/test/hobosupport/module.rdoctest +50 -13
- metadata +51 -44
data/lib/hobosupport/hash.rb
CHANGED
@@ -7,6 +7,7 @@
|
|
7
7
|
|
8
8
|
require 'delegate'
|
9
9
|
require 'singleton'
|
10
|
+
require 'blankslate'
|
10
11
|
|
11
12
|
class Object
|
12
13
|
|
@@ -52,8 +53,12 @@ end
|
|
52
53
|
|
53
54
|
class CallIfAvailable < BlankSlate
|
54
55
|
|
56
|
+
def initialize(target)
|
57
|
+
@target = target
|
58
|
+
end
|
59
|
+
|
55
60
|
def method_missing(name, *args, &b)
|
56
|
-
@
|
61
|
+
@target.send(name, *args, &b) if @target.respond_to?(name)
|
57
62
|
end
|
58
63
|
|
59
64
|
end
|
data/lib/hobosupport/module.rb
CHANGED
@@ -14,12 +14,18 @@ class Module
|
|
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
|
-
def
|
20
|
-
|
19
|
+
def inheriting_cattr_reader(*names)
|
20
|
+
names_with_defaults = (names.pop if names.last.is_a?(Hash)) || {}
|
21
|
+
|
22
|
+
names_with_defaults.each do |name, default|
|
23
|
+
instance_variable_set("@#{name}", default) unless instance_variable_get("@#{name}") != nil || superclass.respond_to?(name)
|
24
|
+
end
|
25
|
+
|
26
|
+
(names + names_with_defaults.keys).each do |name|
|
21
27
|
class_eval %{
|
22
|
-
def
|
28
|
+
def self.#{name}
|
23
29
|
if defined? @#{name}
|
24
30
|
@#{name}
|
25
31
|
elsif superclass.respond_to?('#{name}')
|
@@ -33,7 +39,8 @@ class Module
|
|
33
39
|
# creates a #foo= and #foo? pair, with optional default values, e.g.
|
34
40
|
# bool_attr_accessor :happy => true
|
35
41
|
def bool_attr_accessor(*args)
|
36
|
-
options = args.
|
42
|
+
options = (args.pop if args.last.is_a?(Hash)) || {}
|
43
|
+
|
37
44
|
(args + options.keys).each {|n| class_eval "def #{n}=(x); @#{n} = x; end" }
|
38
45
|
|
39
46
|
args.each {|n| class_eval "def #{n}?; @#{n}; end" }
|
@@ -49,6 +56,12 @@ class Module
|
|
49
56
|
set_field_type(n => TrueClass) if respond_to?(:set_field_type)
|
50
57
|
end
|
51
58
|
end
|
59
|
+
|
60
|
+
def alias_class_method_chain(method, feature)
|
61
|
+
meta_eval do
|
62
|
+
alias_method_chain method, feature
|
63
|
+
end
|
64
|
+
end
|
52
65
|
|
53
66
|
end
|
54
67
|
|
@@ -62,6 +75,7 @@ module Kernel
|
|
62
75
|
m.meta_def :included do |base|
|
63
76
|
base.class_eval &b
|
64
77
|
end
|
78
|
+
m
|
65
79
|
end
|
66
80
|
|
67
81
|
end
|
data/lib/hobosupport.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'activesupport'
|
2
|
+
|
1
3
|
require "hobosupport/fixes"
|
2
4
|
require 'hobosupport/blankslate'
|
3
5
|
require 'hobosupport/methodcall'
|
@@ -11,7 +13,7 @@ require 'hobosupport/module'
|
|
11
13
|
|
12
14
|
module HoboSupport
|
13
15
|
|
14
|
-
VERSION = "0.
|
16
|
+
VERSION = "0.2"
|
15
17
|
|
16
18
|
end
|
17
19
|
|
@@ -27,15 +29,3 @@ class Object
|
|
27
29
|
end
|
28
30
|
|
29
31
|
end
|
30
|
-
|
31
|
-
|
32
|
-
# --- Rails extensions --- #
|
33
|
-
|
34
|
-
# Nice tip from Jamis Buck
|
35
|
-
if defined? ActiveRecord
|
36
|
-
class << ActiveRecord::Base
|
37
|
-
alias_method :[], :find
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
|
@@ -110,6 +110,11 @@ Shorthand for `enum.include?(obj)`
|
|
110
110
|
>> 300.in?(0..10)
|
111
111
|
=> false
|
112
112
|
|
113
|
+
`in?` treats nil as an empty enumeration:
|
114
|
+
|
115
|
+
>> 3.in?(nil)
|
116
|
+
=> false
|
117
|
+
|
113
118
|
## Object#not_in?
|
114
119
|
|
115
120
|
* `obj.not_in?(enum)`
|
@@ -118,3 +123,8 @@ Shorthand for `enum.include?(obj)`
|
|
118
123
|
=> false
|
119
124
|
>> 300.not_in?(0..10)
|
120
125
|
=> true
|
126
|
+
|
127
|
+
`not_in?` treats nil as an empty enumeration:
|
128
|
+
|
129
|
+
>> 3.not_in?(nil)
|
130
|
+
=> true
|
@@ -100,4 +100,25 @@ Returns an array of values for the given keys. Useful for extracting a few optio
|
|
100
100
|
>> {1=>2, 3=>4, 6=>5}.get(1, 3)
|
101
101
|
=> [2, 4]
|
102
102
|
|
103
|
+
## Hash#compact
|
104
|
+
|
105
|
+
* `hash.compact => hash`
|
106
|
+
|
107
|
+
Returns a hash with the same items as the receiver except those where the value is nil
|
108
|
+
|
109
|
+
>> {1=>'a', 2=>nil, 3=>'b'}.compact
|
110
|
+
=> {1=>'a', 3=>'b'}
|
111
|
+
|
112
|
+
## Hash#compact
|
113
|
+
|
114
|
+
* `hash.compact!`
|
115
|
+
|
116
|
+
Removes every pair from the hash where the value is nil
|
117
|
+
|
118
|
+
>> h = {1=>'a', 2=>nil, 3=>'b'}
|
119
|
+
>> h.compact!
|
120
|
+
>> h
|
121
|
+
=> {1=>'a', 3=>'b'}
|
122
|
+
|
123
|
+
|
103
124
|
|
@@ -42,31 +42,68 @@ When a module is included in a class, it gets a callback on the `included` metho
|
|
42
42
|
=> "MY NAME IS C"
|
43
43
|
|
44
44
|
|
45
|
-
## Module#
|
45
|
+
## Module#interiting_cattr_reader
|
46
46
|
|
47
|
-
|
47
|
+
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.
|
48
48
|
|
49
49
|
>>
|
50
50
|
class A
|
51
|
-
|
52
|
-
inheriting_attr_reader :name
|
53
|
-
end
|
54
|
-
@name = "Andy"
|
51
|
+
inheriting_cattr_reader :nickname => "Andy"
|
55
52
|
end
|
56
53
|
|
57
54
|
class B < A; end
|
58
55
|
|
59
|
-
`B` has the same
|
56
|
+
`B` has the same nickname as its superclass `A`
|
60
57
|
|
61
|
-
>> A.
|
58
|
+
>> A.nickname
|
62
59
|
=> "Andy"
|
63
|
-
>> B.
|
60
|
+
>> B.nickname
|
64
61
|
=> "Andy"
|
65
62
|
|
66
|
-
Now we change the
|
63
|
+
Now we change the nickname of `B`. `A` retains it's existing nickname.
|
67
64
|
|
68
|
-
>> class B; @
|
69
|
-
>> B.
|
65
|
+
>> class B; @nickname = "Bob"; end
|
66
|
+
>> B.nickname
|
70
67
|
=> "Bob"
|
71
|
-
>> A.
|
68
|
+
>> A.nickname
|
72
69
|
=> "Andy"
|
70
|
+
|
71
|
+
|
72
|
+
## Kernel#classy_module
|
73
|
+
|
74
|
+
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:
|
75
|
+
|
76
|
+
>>
|
77
|
+
module M
|
78
|
+
def self.included(base)
|
79
|
+
base.send(:extend, ClassMethods)
|
80
|
+
end
|
81
|
+
|
82
|
+
module ClassMethods
|
83
|
+
def foo; 123; end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
class C; include M; end
|
88
|
+
|
89
|
+
>> C.foo
|
90
|
+
=> 123
|
91
|
+
|
92
|
+
It's a shame that such a basic capability isn't more declarative.
|
93
|
+
|
94
|
+
`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
|
+
|
96
|
+
>>
|
97
|
+
MyClassyModule = classy_module do
|
98
|
+
|
99
|
+
def self.foo; 123; end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
>> MyClassyModule.class
|
104
|
+
=> Module
|
105
|
+
>> class C2; include MyClassyModule; end
|
106
|
+
>> C2.foo
|
107
|
+
=> 123
|
108
|
+
|
109
|
+
|
metadata
CHANGED
@@ -1,33 +1,36 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.4
|
3
|
-
specification_version: 1
|
4
2
|
name: hobosupport
|
5
3
|
version: !ruby/object:Gem::Version
|
6
|
-
version: "0.
|
7
|
-
date: 2008-02-11 00:00:00 +00:00
|
8
|
-
summary: Core Ruby extensions from the Hobo project
|
9
|
-
require_paths:
|
10
|
-
- lib
|
11
|
-
email: tom@tomlocke.com
|
12
|
-
homepage: http://hobocentral.net/hobo-support
|
13
|
-
rubyforge_project: hobo
|
14
|
-
description: "== DESCRIPTION: A mixed bag of core Ruby extenstion that have been extracted from the Hobo project. == INSTALL: * sudo gem install hobosupport"
|
15
|
-
autorequire:
|
16
|
-
default_executable:
|
17
|
-
bindir: bin
|
18
|
-
has_rdoc: true
|
19
|
-
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
-
requirements:
|
21
|
-
- - ">"
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 0.0.0
|
24
|
-
version:
|
4
|
+
version: "0.2"
|
25
5
|
platform: ruby
|
26
|
-
signing_key:
|
27
|
-
cert_chain:
|
28
|
-
post_install_message:
|
29
6
|
authors:
|
30
7
|
- Tom Locke
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-03-14 00:00:00 +00:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: hoe
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.5.0
|
23
|
+
version:
|
24
|
+
description: "== DESCRIPTION: A mixed bag of core Ruby extenstion that have been extracted from the Hobo project. == INSTALL: * sudo gem install hobosupport"
|
25
|
+
email: tom@tomlocke.com
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files:
|
31
|
+
- History.txt
|
32
|
+
- Manifest.txt
|
33
|
+
- README.txt
|
31
34
|
files:
|
32
35
|
- History.txt
|
33
36
|
- Manifest.txt
|
@@ -54,28 +57,32 @@ files:
|
|
54
57
|
- test/hobosupport/metaid.rdoctest
|
55
58
|
- test/hobosupport/methodphitamine.rdoctest
|
56
59
|
- test/hobosupport/module.rdoctest
|
57
|
-
|
58
|
-
|
60
|
+
has_rdoc: true
|
61
|
+
homepage: http://hobocentral.net/hobo-support
|
62
|
+
post_install_message:
|
59
63
|
rdoc_options:
|
60
64
|
- --main
|
61
65
|
- README.txt
|
62
|
-
|
63
|
-
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: "0"
|
73
|
+
version:
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: "0"
|
79
|
+
version:
|
70
80
|
requirements: []
|
71
81
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
- !ruby/object:Gem::Version
|
80
|
-
version: 1.5.0
|
81
|
-
version:
|
82
|
+
rubyforge_project: hobo
|
83
|
+
rubygems_version: 1.0.1
|
84
|
+
signing_key:
|
85
|
+
specification_version: 2
|
86
|
+
summary: Core Ruby extensions from the Hobo project
|
87
|
+
test_files: []
|
88
|
+
|