pied_piper 0.1.3 → 0.1.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 89ea6a51147ba81496b97d9693cfe8f8e241b367b82a02fbd263168804c1537c
4
- data.tar.gz: 8f83601c922d1722fd13ba86174c9c84c99aded9b561c97f3652d5e4cfd2f46e
3
+ metadata.gz: d579aeffae1f032f9ee5e820ddbbaa907cdf9126aa053dbbd97d7d31e38cc24b
4
+ data.tar.gz: ca5279f4ddbf50304fa72029a5f3d871beb79f2e90b16f67da14d6bc19a723e4
5
5
  SHA512:
6
- metadata.gz: 138e540a64d9660f99c9bdde4a411f9bfec58308f174eebf6f4a7be105e01265ae13c64f973ec9a9523f7f52fdee5800a39e14d9f5990f665e858631b4b918f4
7
- data.tar.gz: cfad21cda12073d7aa3f69b8a8a937b7838e3e7e6a5eb447b1345d06f2cb6b188ebce313049ecad7783f98787e0eb89bf13ed9173c8fb7b58d9cca23854e2c8a
6
+ metadata.gz: 0c210a151538ab94ef386fd7fa463007545b4a2329b67e59c717c5b2055b9abb854ea661034b6190db1f5965b2d63d238bd783377ba7cc641425df704986de5b
7
+ data.tar.gz: 9a98bd3b029ff085f5d96cc7c1ffa1a915b3e64ec1a3b9d51069597d1c18dd2180a0e7f31049e2faa58129b6ca2602d9b8bb76d854d34ad925eccbf7f6c93f23
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pied_piper (0.1.3)
4
+ pied_piper (0.1.4)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -6,13 +6,15 @@ The inspiration for this gem were `|>` pipes and functional programming in [Elix
6
6
 
7
7
  After trying to introduce the same `|>` pipe operator in Ruby, which I found out isn't possible due to syntactic reasons ( without hacking the underlying C code ), I settled for another well-known pipe operator, the `|` Unix pipe operator.
8
8
 
9
- If you want to read about the inspiration for the name `PiedPiper`, it's an old german fairy tale, the [Pied Piper of Hamelin](https://en.wikipedia.org/wiki/Pied_Piper_of_Hamelin), of a guy who played pipe and hypnotized and lured all children out of town with his music and they were never be seen again.
9
+ If you want to read about the inspiration for the name `PiedPiper`, it's an old german fairy tale, the [Pied Piper of Hamelin](https://en.wikipedia.org/wiki/Pied_Piper_of_Hamelin), a guy who played pipe and hypnotized and lured all children out of town with his music and they were never be seen again.
10
+
11
+ Another thing worth seeing, regarding "Pied Piper" and coding, is [Silicon Valley - Company Name](https://www.youtube.com/watch?v=QJ70b-WRHlU). It's hilarious :-D ( Thanks, Michael! )
10
12
 
11
13
  Despite the word "pipe" there's also another common thing between the fairy tale and pipes in this gem:
12
14
 
13
15
  There's a "piper" object who lures "children" (other objects) away ( through pipes ) until they never be seen again ( are transformed into other objects ). :-)
14
16
 
15
- If you never worked with pipes, this little analogy may help to understand what's happening.
17
+ If you never worked with pipes, this little analogy may help, to understand what's happening.
16
18
 
17
19
  Have fun with PiedPiper and don't let him lure you away... :-)
18
20
 
@@ -58,7 +60,7 @@ Our initial object (e.g: `"rats and kids"`), is passed around through each pipe
58
60
 
59
61
  ### Symbol/String Pipes
60
62
 
61
- 1. A Symbol or String, this calls a method on the piped object with the same name:
63
+ The easiest way to create a pipe is using symbols or strings. This will call the method with the same name as the Symbol/String on the wrapped object:
62
64
 
63
65
  ```ruby
64
66
  p = piper("rats and kids")
@@ -67,7 +69,11 @@ p | :upcase | p.end
67
69
  # => "RATS AND KIDS"
68
70
  ```
69
71
 
70
- Pipes can be chained:
72
+ More about `p.end` below.
73
+
74
+ ### Chaining Pipes
75
+
76
+ Pipes can be chained of course:
71
77
 
72
78
  ```ruby
73
79
  p = piper("rats and kids")
@@ -78,11 +84,13 @@ p | :upcase | :reverse | p.end
78
84
 
79
85
  ### Ending Pipes
80
86
 
81
- Note: Since "piping" is not a native Ruby syntax feature, rather than a method call in disguise (e.g: `p.|(:upcase)`), the underlying `PiedPiper` class, which wraps the initial object (e.g: `"foo"`) and on which the pipe functionality is called, is just a wrapper for the initial object which handles piping logic.
87
+ Note: Since "piping" is not a native Ruby syntax feature, rather than a method call in disguise (e.g: `"foo".|(:upcase)`), the underlying `PiedPiper` class, which wraps the initial object (e.g: `"foo"`) and on which the pipe functionality is called, is just a wrapper for the initial object which handles piping logic.
82
88
 
83
- Everytime you finished a pipe transformation you create a new object of class `PiedPiper`, which wraps the mutated inital object again (e.g: from `"foo"` to `"FOO"`).
89
+ Everytime you transformed an object through a pipe you create a new object of class `PiedPiper`, which wraps the mutated inital object again (e.g: from `"foo"` to `"FOO"`).
84
90
 
85
- We can build pipe-chains this way, but at the end of each pipe-chain, the piped object has to be "unwrapped" again by ending the pipe-chain with the `.end` method on the pipe object or by just writing `PiedPiper::EndOfPipe` or if you have required `pied_piper/kernel` you can just write `p_end`.
91
+ This way, we can build pipe-chains of arbitrary length, but at the end of each pipe-chain, the piped object has to be "unwrapped" again by some kind of "terminator" object.
92
+
93
+ This happens by "terminating" the pipe-chain with the `.end` method, which is defined on every piped object, or by just writing `PiedPiper::EndOfPipe` or if you have required `pied_piper/kernel` you can just write `p_end`.
86
94
 
87
95
  ```ruby
88
96
  p = piper("rats and kids")
@@ -99,13 +107,46 @@ p | :upcase | p_end # when PiedPiper::Kernel was required
99
107
 
100
108
  It would be possible to avoid writing `p.end` at the end of the chain, by implementing the gem in another way, but that would have included to monkey-patch existing Ruby classes, since the `|` method is already implemented by some of them.
101
109
 
102
- I decided against that, since I only wanted to add pipe functionality and not alter existing behaviour in any way.
110
+ I decided against that, since I only wanted to add pipe functionality and not alter existing Ruby behaviour in any way.
103
111
 
104
112
  Thus the `PiedPiper` class was born.
105
113
 
106
- If you want to add pipe functionality everywhere, we already talked about how to implement it above under "Usage".
114
+ ### Ruby and its Kernel module
115
+
116
+ If you want to add pipe functionality everywhere, we already talked about how to implement it above by requiring `pied_piper/kernel".
117
+
118
+ This will provide pipe functionality on every object which has `Object` in one of its superclasses ( thus practically every object in Ruby besides `BasicObject` ) with the least amount of monkey-patching/side-effects, since we only add one Kernel method named `piper` and don't alter existing behaviour.
119
+
120
+ In case you didn't know:
121
+
122
+ `Object` includes `Kernel` as a module.
123
+
124
+ Methods who are intended to be globally available, like `puts` and `gets`, and who aren't intended to be available with an explicit receiver like `"foo".puts` are defined as private instance methods on `Kernel`.
125
+
126
+ Private instance methods can only be called with an implicit receiver (implicit self) in Ruby.
127
+
128
+ That's why things like this work, because were always "inside" an object:
129
+
130
+ ```ruby
131
+ puts self
132
+ # main
133
+ # nil
134
+
135
+ # implicit receiver for puts
136
+ puts "foo"
137
+ ```
138
+
139
+ but this doesn't:
140
+
141
+ ```ruby
142
+ # explicit receiver for puts
143
+ self.puts "foo"
144
+ # => NoMethodError: private method `puts' called for main:Object
145
+ ```
146
+
147
+ So if you want to provide functionality that's available everywhere like `puts` the usual approach is to define a private instance method on Kernel.
107
148
 
108
- This will make you use pipe functionality everywhere with the least amount of side-effects, since it only adds and doesn't alter existing behaviour.
149
+ That's what has been done with the `piper` and `p_end` method :-)
109
150
 
110
151
  ### Array Pipes
111
152
 
@@ -2,6 +2,8 @@ require 'pied_piper'
2
2
 
3
3
  module PiedPiper::Kernel
4
4
  ::Kernel.class_eval do
5
+ private
6
+
5
7
  def piper(obj)
6
8
  PiedPiper.new(obj)
7
9
  end
@@ -1,3 +1,3 @@
1
1
  class PiedPiper
2
- VERSION = '0.1.3'.freeze
2
+ VERSION = '0.1.4'.freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pied_piper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christoph Weegen