chainable_methods 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 634ac2aaad7197f6de1f6a9e3fd0b6487813e896
4
- data.tar.gz: 237ab10f99fcf6386b36b2ac1f5e03101fe21945
3
+ metadata.gz: 620ba46af2bafae375678b698d4cc880f44c24b8
4
+ data.tar.gz: 9525185333b1e4cb6e2a9481758c7e4323984173
5
5
  SHA512:
6
- metadata.gz: 21a214e12eb61e11418bacec469bfaa629037b98ddd808560c746bb523585f12b159e8ffdc4e0e7b4a5c390cc1fc9d21dee8d2eba777f0a50a93a574688e774b
7
- data.tar.gz: 8784f1bac5d1392ae5cf53520acf9cbaf2b8570d4e605843777a77bd0ea02f09c4ebbcce44d455d89995131ad4dba8c9b153b012e330a9131de117ae212e6b05
6
+ metadata.gz: b8ddb94ce68e740265f41cc988ba93a6bdaf73fe09b2049bb57092ecf77610762393f040f76722df3d7d8d90911e65170bbe660cb3fc2076ded534a78c88df19
7
+ data.tar.gz: 868f95a4fb3322b3977b412679e79ce8cdb537b91217926da4d1d11b492027853145068b9b74775d0f04ecc6b3506c3603c6ca8e58b6e7a0605fe741cfa39b96
data/.gitignore CHANGED
@@ -8,3 +8,5 @@
8
8
  /spec/reports/
9
9
  /tmp/
10
10
  *.gem
11
+ .env
12
+ *.gem
@@ -1,4 +1,15 @@
1
1
  language: ruby
2
+ cache: bundler
2
3
  rvm:
3
- - 2.3.0
4
- before_install: gem install bundler -v 1.11.2
4
+ - 2.3.1
5
+ before_install:
6
+ - gem install bundler -v 1.11.2
7
+ script:
8
+ - xvfb-run bundle exec rake test
9
+ notifications:
10
+ email:
11
+ recipients:
12
+ - boss@akitaonrails.com
13
+ addons:
14
+ code_climate:
15
+ repo_token: 9336cb6031790cc0f5501db2d74c8671c6ff1b74eb2883c0456a5722a775d655
data/README.md CHANGED
@@ -1,20 +1,30 @@
1
1
  # Chainable Methods
2
2
 
3
+ <a href="https://codeclimate.com/repos/57659a6019dc0b459200205b/feed"><img src="https://codeclimate.com/repos/57659a6019dc0b459200205b/badges/fbf8f254fa716b481c40/gpa.svg" /></a>
4
+
5
+ <a href="https://travis-ci.org/akitaonrails/chainable_methods"><img src="https://travis-ci.org/akitaonrails/chainable_methods.svg?branch=master" /></a>
6
+
7
+ <a href="https://codeclimate.com/repos/57659a6019dc0b459200205b/coverage"><img src="https://codeclimate.com/repos/57659a6019dc0b459200205b/badges/fbf8f254fa716b481c40/coverage.svg" /></a>
8
+
9
+ <a href="https://codeclimate.com/repos/57659a6019dc0b459200205b/feed"><img src="https://codeclimate.com/repos/57659a6019dc0b459200205b/badges/fbf8f254fa716b481c40/issue_count.svg" /></a>
10
+
3
11
  The Elixir language is doing great and within its many incredible features is the famous "Pipe Operator". Other popular functional languages like Haskell and F# sport a similar feature.
4
12
 
5
13
  It allows you to do constructs such as this:
6
14
 
7
- ```
15
+ ```elixir
16
+ require Integer
8
17
  1..100_000
9
18
  |> Stream.map(&(&1 * 3))
10
- |> Stream.filter(odd?)
19
+ |> Stream.filter(&(Integer.is_odd(&1)))
11
20
  |> Enum.sum
12
21
  ```
13
22
 
14
23
  In a nutshell, this is taking the previous returning value and automatically passing it as the first argument of the following function call, so it's sort of equivalent to do this:
15
24
 
16
- ```
17
- Enum.sum(Enum.filter(Enum.map(1..100_000, &(&1 * 3)), odd?))
25
+ ```elixir
26
+ require Integer
27
+ Enum.sum(Enum.filter(Enum.map(1..100_000, &(&1 * 3)), &(Integer.is_odd(&1))))
18
28
  ```
19
29
 
20
30
  (In F# it's even more important to make proper left-to-right type inference.)
@@ -23,13 +33,13 @@ This is how we would usually do it, but with the Pipe Operator it becomes incred
23
33
 
24
34
  Now, in the Ruby world, we would prefer to do it in a more Object Oriented fashion, with chained methods like this:
25
35
 
26
- ```
36
+ ```ruby
27
37
  object.method_1.method_2(argument).method_3 { |x| do_something(x) }.method_4
28
38
  ```
29
39
 
30
40
  This is how we do things in Rails, for example, Arel coming into mind:
31
41
 
32
- ```
42
+ ```ruby
33
43
  User.first.comments.where(created_at: 2.days.ago..Time.current).limit(5)
34
44
  ```
35
45
 
@@ -57,7 +67,7 @@ Or install it yourself as:
57
67
 
58
68
  ## Usage
59
69
 
60
- ```
70
+ ```ruby
61
71
  # create your Module with composable 'functions'
62
72
  module MyModule
63
73
  include ChainableMethods
@@ -79,7 +89,7 @@ end
79
89
 
80
90
  And now we can build something like this:
81
91
 
82
- ```
92
+ ```ruby
83
93
  MyModule.
84
94
  chain_from(some_text).
85
95
  upcase. # this calls a method from the string in 'some_text'
@@ -91,7 +101,7 @@ MyModule.
91
101
 
92
102
  And that's it. This would be the equivalent of doing something more verbose like this:
93
103
 
94
- ```
104
+ ```ruby
95
105
  a = some_text.upcase
96
106
  b = MyModule.method_a(a)
97
107
  c = MyModule.method_b(b, "something")
@@ -102,7 +112,7 @@ The recommend approach is to create modules to serve as "namespaces" for collect
102
112
 
103
113
  Sometimes we have adhoc transformations. We usually have to storage intermediate states as dangling variables like this:
104
114
 
105
- ```
115
+ ```ruby
106
116
  text = "hello http:///www.google.com world"
107
117
  url = URI.extract(text).first }
108
118
  uri = URI.parse(url)
@@ -112,10 +122,10 @@ title = Nokogiri::HTML(body).css("h1").first.text.strip
112
122
 
113
123
  Or now, we can just chain them together like this:
114
124
 
115
- ```
125
+ ```ruby
116
126
  CM("hello http:///www.google.com world")
117
- .chain { |text| URI.extract(text).first }
118
- .chain { |url| URI.parse(url) }
127
+ .URI.extract.first
128
+ .URI.parse
119
129
  .chain { |uri| open(uri).read }
120
130
  .chain { |body| Nokogiri::HTML(body).css("h1") }
121
131
  .first.text.strip
@@ -150,7 +160,7 @@ v0.1.1
150
160
  v0.1.2
151
161
  - introduces a shortcut global method 'CM' to be used like this:
152
162
 
153
- ```
163
+ ```ruby
154
164
  CM(2, ['a', 'b', 'c'])
155
165
  .[]
156
166
  .upcase
@@ -164,6 +174,9 @@ v0.1.3
164
174
  v0.1.4
165
175
  - makes the ChainableMethods module "includable" and it automatically makes all instance methods of the parent Module as class methods that can be easily chainable without having to declare all of them as `def self.method` first. So you can do it like this:
166
176
 
177
+ v0.2.1
178
+ - use a const_get trick to allow to chain Module or Class names directly in the dot notation. Inspired by [this gist](https://gist.github.com/bkerley/754df43c98e116e82003). Kudos to @bkerley for the idea and @BonzoESC for bringing it out.
179
+
167
180
  ## License
168
181
 
169
182
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -26,4 +26,5 @@ Gem::Specification.new do |spec|
26
26
  spec.add_development_dependency 'nokogiri', '~> 1.6', '>= 1.6.8'
27
27
  spec.add_development_dependency 'vcr', '~> 3.0', '>= 3.0.3'
28
28
  spec.add_development_dependency 'webmock', '~> 2.1', '>= 2.1.0'
29
+ spec.add_development_dependency 'codeclimate-test-reporter', '~> 0.5', '>= 0.5.2'
29
30
  end
@@ -27,7 +27,7 @@ http_interactions:
27
27
  body:
28
28
  encoding: UTF-8
29
29
  string: ''
30
- http_version:
30
+ http_version:
31
31
  recorded_at: Sat, 18 Jun 2016 18:45:29 GMT
32
32
  - request:
33
33
  method: get
@@ -65,7 +65,7 @@ http_interactions:
65
65
  X-Ua-Compatible:
66
66
  - IE=Edge,chrome=1
67
67
  Set-Cookie:
68
- - _gh_sess=eyJzZXNzaW9uX2lkIjoiZWM2ZWE4ZWQ3ZjE4NmZiYTY1ODhhODYwNWVjMzYxYTkiLCJzcHlfcmVwbyI6ImFraXRhb25yYWlscy9jaGFpbmFibGVfbWV0aG9kcyIsInNweV9yZXBvX2F0IjoxNDY2Mjc1NTMxLCJfY3NyZl90b2tlbiI6IlRsU1dUd2ZJbzN0Q1lGdWlabTNsMUZMbm1qdk0xM051cHk2TlpHNmJlSXc9IiwiZmxhc2giOnsiZGlzY2FyZCI6WyJhbmFseXRpY3NfbG9jYXRpb24iXSwiZmxhc2hlcyI6eyJhbmFseXRpY3NfbG9jYXRpb24iOiIvPHVzZXItbmFtZT4vPHJlcG8tbmFtZT4ifX19--861decdf242a0f10dc165c3b662ad8bf56396532;
68
+ - _gh_sess=eyJzZXNzaT4ifX19--861decdf56396532;
69
69
  path=/; secure; HttpOnly
70
70
  - _octo=GH1.1.49047256.1466275531; domain=.github.com; path=/; expires=Mon,
71
71
  18 Jun 2018 18:45:31 -0000
@@ -1528,6 +1528,6 @@ http_interactions:
1528
1528
  NDgtMS40OEw2IDYuNTJsMy43NS0zLjc1IDEuNDggMS40OHoiPjwvcGF0aD48
1529
1529
  L3N2Zz4KICAgIDwvYnV0dG9uPgogIDwvZGl2Pgo8L2Rpdj4KCiAgPC9ib2R5
1530
1530
  Pgo8L2h0bWw+Cgo=
1531
- http_version:
1531
+ http_version:
1532
1532
  recorded_at: Sat, 18 Jun 2016 18:45:30 GMT
1533
1533
  recorded_with: VCR 3.0.3
@@ -35,6 +35,10 @@ module ChainableMethods
35
35
  end
36
36
 
37
37
  def method_missing(method_name, *args, &block)
38
+ if is_constant?(method_name)
39
+ return ChainableMethods::Link.new( @state, ::Kernel.const_get(method_name) )
40
+ end
41
+
38
42
  local_response = @state.respond_to?(method_name)
39
43
  context_response = @context.respond_to?(method_name)
40
44
 
@@ -52,5 +56,13 @@ module ChainableMethods
52
56
  def unwrap
53
57
  @state
54
58
  end
59
+
60
+ private def is_constant?(method_name)
61
+ method_name_start = method_name.to_s.chars.first
62
+ if method_name_start =~ /\A[[:alpha:]]+\z/i
63
+ return ( method_name_start.upcase == method_name_start )
64
+ end
65
+ false
66
+ end
55
67
  end
56
68
  end
@@ -1,3 +1,3 @@
1
1
  module ChainableMethods
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chainable_methods
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - AkitaOnRails
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-06-18 00:00:00.000000000 Z
11
+ date: 2016-06-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -126,6 +126,26 @@ dependencies:
126
126
  - - ">="
127
127
  - !ruby/object:Gem::Version
128
128
  version: 2.1.0
129
+ - !ruby/object:Gem::Dependency
130
+ name: codeclimate-test-reporter
131
+ requirement: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - "~>"
134
+ - !ruby/object:Gem::Version
135
+ version: '0.5'
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: 0.5.2
139
+ type: :development
140
+ prerelease: false
141
+ version_requirements: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '0.5'
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ version: 0.5.2
129
149
  description: The idea is to allow for a more functional way of organizing code within
130
150
  a module and being able to chain those methdos together, where the result of the
131
151
  first method serves as the first argument of the next method in the chain.
@@ -168,7 +188,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
168
188
  version: '0'
169
189
  requirements: []
170
190
  rubyforge_project:
171
- rubygems_version: 2.5.1
191
+ rubygems_version: 2.6.4
172
192
  signing_key:
173
193
  specification_version: 4
174
194
  summary: Just a simple experiment to allow for a behavior similar to [Elixir|Haskell|F#]'s