attr_extras 1.4.0 → 1.5.0

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.
data/README.md CHANGED
@@ -22,6 +22,9 @@ Defines a `.fooable?` class method that delegates to an instance method.
22
22
  `attr_id_query :foo?, :bar?`<br>
23
23
  Defines query methods like `foo?`, which is true iff `foo_id` is truthy. Goes well with Active Record.
24
24
 
25
+ `attr_query :foo?, :bar?`<br>
26
+ Defines query methods like `foo?`, which is true iff `foo` is truthy.
27
+
25
28
  Findability has been a central consideration.
26
29
  Hence the long name `attr_initialize`, so you see it when scanning for the initializer;
27
30
  and the enforced questionmarks with `attr_id_query :foo?`, so you can search for that method.
@@ -34,6 +37,7 @@ class MyClass
34
37
  attr_initialize :foo, :bar
35
38
  attr_private :foo
36
39
  attr_id_query :item?
40
+ attr_query :oof?
37
41
 
38
42
  def oof
39
43
  foo.reverse
@@ -48,6 +52,7 @@ x = MyClass.new("Foo!", "Bar!")
48
52
  x.oof # => "!ooF"
49
53
  x.foo # NoMethodError: private method `foo' called.
50
54
  x.item? # => true
55
+ x.oof? # => true
51
56
 
52
57
  class MyMethodObject
53
58
  method_object :fooable?,
@@ -70,6 +75,45 @@ x = MyHashyObject.new("Foo!", bar: "Bar!", baz: "Baz!")
70
75
  x.bar # => "Bar!"
71
76
  ```
72
77
 
78
+ ## Why not use `Struct`?
79
+
80
+ `Struct` has some behavior you may not expect. Say you have this:
81
+
82
+ ``` ruby
83
+ class Greeter < Struct.new(:user)
84
+ def greet
85
+ puts "Hello #{user.name}!"
86
+ end
87
+ end
88
+ ```
89
+
90
+ The `Struct` won't actually require you to provide any arguments. You could do this and it won't complain until `nil.name` explodes on you:
91
+
92
+ ``` ruby
93
+ Greeter.new.greet
94
+ ```
95
+
96
+ Also, the Greeter will have a public `user` accessor even if you only need it internally, so your public interface is unnecessarily large.
97
+
98
+ Further, inheriting from `Struct` arguably suggests that you have a mere data structure, not a full-blown class with rich behavior.
99
+
100
+ With `attr_extras`, you have none of these issues:
101
+
102
+ ``` ruby
103
+ class Greeter
104
+ pattr_initialize :user
105
+
106
+ def greet
107
+ puts "Hello #{user.name}!"
108
+ end
109
+ end
110
+ ```
111
+
112
+ ## Why not use `private; attr_reader :foo`?
113
+
114
+ Instead of `attr_private :foo`, you could do `private; attr_reader :foo`.
115
+
116
+ Other than being more to type, declaring `attr_reader` after `private` will actually give you a warning (deserved or not) if you run Ruby with warnings turned on.
73
117
 
74
118
  ## Installation
75
119
 
@@ -85,7 +129,6 @@ Or install it yourself as:
85
129
 
86
130
  gem install attr_extras
87
131
 
88
-
89
132
  ## License
90
133
 
91
134
  Copyright (c) 2012 [Barsoom AB](http://barsoom.se)
data/lib/attr_extras.rb CHANGED
@@ -39,15 +39,25 @@ module AttrExtras
39
39
  pattr_initialize *names
40
40
  end
41
41
 
42
+ def attr_query(*names)
43
+ attr_query_with_suffix(*names, "")
44
+ end
45
+
42
46
  def attr_id_query(*names)
47
+ attr_query_with_suffix(*names, "_id")
48
+ end
49
+
50
+ private
51
+
52
+ def attr_query_with_suffix(*names, suffix)
43
53
  names.each do |name|
44
54
  name = name.to_s
45
55
 
46
56
  raise "#{__method__} wants `#{name}?`, not `#{name}`." unless name.end_with?("?")
47
57
 
48
- define_method(name) do # def foo?
49
- !!send("#{name.chop}_id") # !!send("foo_id")
50
- end # end
58
+ define_method(name) do # def foo?
59
+ !!send("#{name.chop}#{suffix}") # !!send("foo_id")
60
+ end # end
51
61
  end
52
62
  end
53
63
  end
@@ -1,3 +1,3 @@
1
1
  module AttrExtras
2
- VERSION = "1.4.0"
2
+ VERSION = "1.5.0"
3
3
  end
@@ -13,7 +13,8 @@ end
13
13
 
14
14
  class QueryExample
15
15
  attr_id_query :baz?, :boink?
16
- attr_accessor :baz_id
16
+ attr_query :flurp?
17
+ attr_accessor :baz_id, :flurp
17
18
  end
18
19
 
19
20
  class MethodObjectExample
@@ -88,3 +89,16 @@ describe Object, ".attr_id_query" do
88
89
  lambda { Object.attr_id_query(:foo) }.must_raise RuntimeError
89
90
  end
90
91
  end
92
+
93
+ describe Object, ".attr_query" do
94
+ it "creates attribute query methods" do
95
+ example = QueryExample.new
96
+ refute example.flurp?
97
+ example.flurp = "!"
98
+ assert example.flurp?
99
+ end
100
+
101
+ it "requires a trailing questionmark" do
102
+ lambda { Object.attr_query(:foo) }.must_raise RuntimeError
103
+ end
104
+ end
metadata CHANGED
@@ -1,60 +1,34 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: attr_extras
3
- version: !ruby/object:Gem::Version
4
- hash: 7
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.5.0
5
5
  prerelease:
6
- segments:
7
- - 1
8
- - 4
9
- - 0
10
- version: 1.4.0
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Henrik Nyh
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2013-02-21 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2013-07-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
21
15
  name: rake
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &70260295305400 !ruby/object:Gem::Requirement
24
17
  none: false
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- hash: 3
29
- segments:
30
- - 0
31
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
32
22
  type: :development
33
- version_requirements: *id001
34
- - !ruby/object:Gem::Dependency
35
- name: minitest
36
23
  prerelease: false
37
- requirement: &id002 !ruby/object:Gem::Requirement
38
- none: false
39
- requirements:
40
- - - ">="
41
- - !ruby/object:Gem::Version
42
- hash: 3
43
- segments:
44
- - 0
45
- version: "0"
46
- type: :development
47
- version_requirements: *id002
24
+ version_requirements: *70260295305400
48
25
  description:
49
- email:
26
+ email:
50
27
  - henrik@nyh.se
51
28
  executables: []
52
-
53
29
  extensions: []
54
-
55
30
  extra_rdoc_files: []
56
-
57
- files:
31
+ files:
58
32
  - .gitignore
59
33
  - .rvmrc
60
34
  - .travis.yml
@@ -67,36 +41,33 @@ files:
67
41
  - spec/attr_extras_spec.rb
68
42
  homepage: https://github.com/barsoom/attr_extras
69
43
  licenses: []
70
-
71
44
  post_install_message:
72
45
  rdoc_options: []
73
-
74
- require_paths:
46
+ require_paths:
75
47
  - lib
76
- required_ruby_version: !ruby/object:Gem::Requirement
48
+ required_ruby_version: !ruby/object:Gem::Requirement
77
49
  none: false
78
- requirements:
79
- - - ">="
80
- - !ruby/object:Gem::Version
81
- hash: 3
82
- segments:
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ segments:
83
55
  - 0
84
- version: "0"
85
- required_rubygems_version: !ruby/object:Gem::Requirement
56
+ hash: 1437049872274333765
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
58
  none: false
87
- requirements:
88
- - - ">="
89
- - !ruby/object:Gem::Version
90
- hash: 3
91
- segments:
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ segments:
92
64
  - 0
93
- version: "0"
65
+ hash: 1437049872274333765
94
66
  requirements: []
95
-
96
67
  rubyforge_project:
97
- rubygems_version: 1.8.24
68
+ rubygems_version: 1.8.10
98
69
  signing_key:
99
70
  specification_version: 3
100
71
  summary: Takes some boilerplate out of Ruby with methods like attr_initialize.
101
- test_files:
72
+ test_files:
102
73
  - spec/attr_extras_spec.rb