question_mark_methods 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +114 -0
- data/Rakefile +5 -0
- data/lib/question_mark_method.rb +31 -0
- data/lib/question_mark_methods/version.rb +3 -0
- data/lib/question_mark_methods.rb +4 -0
- data/question_mark_methods.gemspec +19 -0
- data/spec/question_mark_method_spec.rb +51 -0
- data/spec/spec_helper.rb +1 -0
- metadata +59 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Roy Young
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
# QuestionMarkMethods
|
2
|
+
|
3
|
+
I love the attribute query methods in ActiveRecord, Query methods allow me to us whether an attribute value is present. For example:
|
4
|
+
|
5
|
+
```ruby
|
6
|
+
user = User.new(:name => "David")
|
7
|
+
user.name? # => true
|
8
|
+
|
9
|
+
anonymous = User.new(:name => "")
|
10
|
+
anonymous.name? # => false
|
11
|
+
```
|
12
|
+
|
13
|
+
I love the question mark at the end of the method name, because it makes the code more readable. But what should we do if we do not use ActiveRecord? Also you can implement like below:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
class User
|
17
|
+
#initialize method...
|
18
|
+
|
19
|
+
def is_admin?
|
20
|
+
@is_admin
|
21
|
+
end
|
22
|
+
end
|
23
|
+
```
|
24
|
+
|
25
|
+
But I am tired of this, all I need it is just adding a question mark at the end of the method name, so I build this gem to reduce that codes.
|
26
|
+
|
27
|
+
## Installation
|
28
|
+
|
29
|
+
Add this line to your application's Gemfile:
|
30
|
+
|
31
|
+
gem 'question_mark_methods'
|
32
|
+
|
33
|
+
And then execute:
|
34
|
+
|
35
|
+
$ bundle
|
36
|
+
|
37
|
+
Or install it yourself as:
|
38
|
+
|
39
|
+
$ gem install question_mark_methods
|
40
|
+
|
41
|
+
## Usage
|
42
|
+
|
43
|
+
First, Include it in your class
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
require 'QuestionMarkMethods'
|
47
|
+
|
48
|
+
class User
|
49
|
+
include QuestionMarkMethods
|
50
|
+
end
|
51
|
+
```
|
52
|
+
|
53
|
+
and then use it just like attribute query methods in ActiveRecord. For example
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
class User
|
57
|
+
include QuestionMarkMethods
|
58
|
+
|
59
|
+
def initialize(name, is_charged)
|
60
|
+
@name = name
|
61
|
+
@is_charged = is_charged
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
user = User.new("alice", true)
|
66
|
+
user.is_charged? # => true
|
67
|
+
user.name? # => true
|
68
|
+
```
|
69
|
+
|
70
|
+
**You can also customize your method names**
|
71
|
+
|
72
|
+
Add a macros `add_question_mark_methods`:
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
class User
|
76
|
+
#...
|
77
|
+
|
78
|
+
add_question_mark_methods has_a_name?: :name, has_been_charged?: :is_charged
|
79
|
+
|
80
|
+
#instance methods...
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
user = User.new("alice", true)
|
85
|
+
user.has_a_name? # => true
|
86
|
+
user.has_been_charged? # => false
|
87
|
+
```
|
88
|
+
|
89
|
+
**Why don't use alias_method()?**
|
90
|
+
|
91
|
+
let's look at how to use alias_method to implement this.
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
class User
|
95
|
+
attr_reader :is_charged, :name
|
96
|
+
|
97
|
+
alias_method :has_been_charged?, :is_charged
|
98
|
+
alias_method :has_a_name?, :name
|
99
|
+
|
100
|
+
#same initialize...
|
101
|
+
end
|
102
|
+
|
103
|
+
user = User.new("alice", true)
|
104
|
+
user.has_been_charged? # => true
|
105
|
+
user.has_a_name? # => "alice"
|
106
|
+
```
|
107
|
+
|
108
|
+
When we using alias_method to do the same thing, We need to add `attr_reader` first and use `alias_method` twice to define two aliases. Maybe you have noticed the biggest problem, `user.has_a_name?` returns the value of @name, but we need a boolean in this case.
|
109
|
+
|
110
|
+
## About
|
111
|
+
|
112
|
+
I built this for fun and practicing metaprogramming, after finishing the mid-level course of [Tealeaf Academy](http://gotealeaf.com).
|
113
|
+
|
114
|
+
Thanks @knwang!
|
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
module QuestionMarkMethod
|
2
|
+
def method_missing(method_name)
|
3
|
+
if md = /\?$/.match(method_name.to_s)
|
4
|
+
return_boolean_value_of_attribute_related_with(md.pre_match)
|
5
|
+
else
|
6
|
+
super
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.included(base)
|
11
|
+
base.extend(ClassMethods)
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
def add_question_mark_methods(options)
|
16
|
+
self.class_eval do
|
17
|
+
options.each do |new_method_name, old_method_name|
|
18
|
+
define_method new_method_name do
|
19
|
+
return_boolean_value_of_attribute_related_with(old_method_name.to_s)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
def return_boolean_value_of_attribute_related_with(method_name)
|
28
|
+
attribute = "@" + method_name
|
29
|
+
!!instance_variable_get(attribute)
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'question_mark_methods/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "question_mark_methods"
|
8
|
+
gem.version = QuestionMarkMethods::VERSION
|
9
|
+
gem.authors = ["Roy Young"]
|
10
|
+
gem.email = ["zhuoyuyang@gmail.com"]
|
11
|
+
gem.description = %q{give boolean attribute a question mark method}
|
12
|
+
gem.summary = ""
|
13
|
+
gem.homepage = ""
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe QuestionMarkMethod do
|
4
|
+
let(:alice) { Member.new("alice", true) }
|
5
|
+
let(:bob) { Member.new("bob", false) }
|
6
|
+
|
7
|
+
context "end with a question mark" do
|
8
|
+
it "returns the original method result of false" do
|
9
|
+
bob.charged?.should == false
|
10
|
+
end
|
11
|
+
|
12
|
+
it "returns the original method result of true" do
|
13
|
+
alice.name?.should == true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "not end with a question mark" do
|
18
|
+
it "raise an NoMethodError" do
|
19
|
+
lambda { alice.is_charged }.should raise_error(NoMethodError)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when added macros" do
|
24
|
+
before do
|
25
|
+
Member.class_eval do
|
26
|
+
add_question_mark_methods is_charged?: :charged, has_a_name?: :name
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns true when has a name" do
|
31
|
+
alice.has_a_name?.should == true
|
32
|
+
end
|
33
|
+
|
34
|
+
it "returns true when has beed charged" do
|
35
|
+
alice.is_charged?.should == true
|
36
|
+
end
|
37
|
+
|
38
|
+
it "raises a NoMethodError" do
|
39
|
+
lambda {alice.has_been_charged }.should raise_error(NoMethodError)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class Member
|
45
|
+
include QuestionMarkMethod
|
46
|
+
|
47
|
+
def initialize(not_a_boolean_value, boolean_value)
|
48
|
+
@name = not_a_boolean_value
|
49
|
+
@charged = boolean_value
|
50
|
+
end
|
51
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'question_mark_method'
|
metadata
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: question_mark_methods
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Roy Young
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-05-02 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: give boolean attribute a question mark method
|
15
|
+
email:
|
16
|
+
- zhuoyuyang@gmail.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- .gitignore
|
22
|
+
- .rspec
|
23
|
+
- Gemfile
|
24
|
+
- LICENSE.txt
|
25
|
+
- README.md
|
26
|
+
- Rakefile
|
27
|
+
- lib/question_mark_method.rb
|
28
|
+
- lib/question_mark_methods.rb
|
29
|
+
- lib/question_mark_methods/version.rb
|
30
|
+
- question_mark_methods.gemspec
|
31
|
+
- spec/question_mark_method_spec.rb
|
32
|
+
- spec/spec_helper.rb
|
33
|
+
homepage: ''
|
34
|
+
licenses: []
|
35
|
+
post_install_message:
|
36
|
+
rdoc_options: []
|
37
|
+
require_paths:
|
38
|
+
- lib
|
39
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
46
|
+
none: false
|
47
|
+
requirements:
|
48
|
+
- - ! '>='
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '0'
|
51
|
+
requirements: []
|
52
|
+
rubyforge_project:
|
53
|
+
rubygems_version: 1.8.24
|
54
|
+
signing_key:
|
55
|
+
specification_version: 3
|
56
|
+
summary: ''
|
57
|
+
test_files:
|
58
|
+
- spec/question_mark_method_spec.rb
|
59
|
+
- spec/spec_helper.rb
|