immanence 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NjE2MTIzMWJhMTcxMGNmNjQyNGE4MjlmNjY3YzI2NjA3NDE0YWFhNA==
4
+ MDcyOTJhNmQ0NTc5MDU4MjhkYTVmMGJiNTRmZjU5MWU4NTRmNzY3ZQ==
5
5
  data.tar.gz: !binary |-
6
- NjU0OGM3ODk1MGI1MDcyZjk1ZjcyNmRlYzA0YWI5MTc2MzNkYWY5Mg==
6
+ MDJkZmNlNGQ1ZDQ5MDJiMjRhMTIxMjAyNTdmMGM0NWU0ZmYyN2RlOQ==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- MzVkZmUyOTgzNzU4Mzk4MzgxOWM2OGJhODhiMTM1NzI1NzU4MzNmMGE5ZjI5
10
- N2NiN2I0ZWFkZDU2NzBlODI5NjUxZGU5NDNiOGQzYThhYzFkZWY5MzQzYzE1
11
- ODYxYjdhMTQ5ODUxNDE5MWUwNGViYmE4NmRhODliOTY4NWY3MDU=
9
+ N2IzMTc4Mjg4Y2Y4MDM3MTBjYzYyOTA0MGI3NDZkN2RkOWE4NWFmYjcxNzNk
10
+ ZDFmMzQyNmUzYzQ0ZDQ2ZGIxYTE1MjliZDZiZjYyNGUwYjhiNDA3Mzg1Y2E1
11
+ MmIwODhhMzI2MTliZTgwYjE0NGU0MmNiNjNhZDNkZjQ0YzMxYjY=
12
12
  data.tar.gz: !binary |-
13
- Y2EzN2EwMmMwYzhkNWY4ZjU0NzRjY2QxMjEwNGQ4YjllNzIwZDFjNzYzMmQ0
14
- ZTc2ZDQ4MTYxZjczNmExOWEyYjE5MmE5NzE0OWJhMGM3Y2UxMjdiZTI2ZjBi
15
- Y2QzOTc2ODdjNWM5ZDFmMDc4M2E0YmRlMDc1OTZlZWZkZWM0YTI=
13
+ NjE0MGRkN2I2NDhjZGRjNmU4YzM1ODVjNDYzMWIwNDAzNmUxN2M1NjliMjE2
14
+ MmNjYzNkMWQ5ZWE0ZTg0NzRkOTQyYmJhYTRhYmZkY2NkZjk3ZmQ3M2YwOTIx
15
+ ZDQwZDIzYmY2MTI2OWY1NDJlOGUyNTJjNTQwZDQ4NDc2NTJkNzU=
data/README.md CHANGED
@@ -1 +1,26 @@
1
- > [...] when I stub my toe, it is because I do not have the proper set of architectural landing sites in place. That is, my architectural body has not assembled enough clues to connect itself properly to its surroundings. Sites of reversible destiny are designed to be as complex as our most innate mechanisms of our perception. It might take an hour to go from one room to another, and I might live there in a continual state of deja vu as I experience a repetition of slightly differing perceptions. Yet, I will be involved in a constant critique of my own experience. I will see. I will live. Perhaps for the first time. —Arakawa and Gins
1
+ > [...] when I stub my toe, it is because I do not have the proper set of architectural landing sites in place.
2
+ > That is, my architectural body has not assembled enough clues to connect itself properly to its surroundings.
3
+ > Sites of reversible destiny are designed to be as complex as our most innate mechanisms of our perception.
4
+ > It might take an hour to go from one room to another, and I might live there in a continual state of deja vu as I experience a repetition of slightly differing perceptions.
5
+ > Yet, I will be involved in a constant critique of my own experience.
6
+ > I will see.
7
+ > I will live.
8
+ > Perhaps for the first time.
9
+ >
10
+ > —Arakawa and Madeline Gins
11
+
12
+ **Immanence** is a DSL for handling web requests in Ruby, built on top of Rack. To execute routes it calculates the [Levenshtein distance](http://en.wikipedia.org/wiki/Levenshtein_distance) between incoming requests and routes defined in the DSL then executes the most likely candidate. *Something will always be executed.* Objects are rendered by calling `>>` on `self` with the object to be rendered as the argument. Objects are serialized into JSON via Oj. Incoming JSON is automatically parsed and available in the `@request` object.
13
+
14
+ This is less a useful piece of software and more of a stylistic exercise.
15
+
16
+ ```ruby
17
+ class Application < Immanence::Control
18
+ route :get, "/fields/:id" do
19
+ self >> Field.find(@params[:id])
20
+ end
21
+
22
+ route :post, "/fields" do
23
+ self >> Field.create(@request.input)
24
+ end
25
+ end
26
+ ```
@@ -0,0 +1,5 @@
1
+ # encoding: UTF-8
2
+
3
+ module Kernel
4
+ alias_method :λ, :lambda
5
+ end
@@ -2,4 +2,8 @@ class Object
2
2
  def meta_def(method, &block)
3
3
  (class << self; self end).send(:define_method, method, &block)
4
4
  end
5
+
6
+ def let
7
+ yield self
8
+ end
5
9
  end
data/lib/immanence.rb CHANGED
@@ -1,6 +1,9 @@
1
+ # encoding: UTF-8
2
+
1
3
  require "rack"
2
4
  require "oj"
3
5
 
6
+ require "core_ext/kernel"
4
7
  require "core_ext/hash"
5
8
  require "core_ext/object"
6
9
 
@@ -8,12 +11,10 @@ module Immanence
8
11
  class Request < Struct.new(:verb, :path, :input); end
9
12
 
10
13
  class Control
11
- I =-> i { Oj.load(i) }
12
- O =-> o { Oj.dump(o, mode: :compat) }
13
-
14
- PROBLEM = "[...] from a problem to the accidents that condition and resolve it."
14
+ I = λ { |i| Oj.load(i) }
15
+ O = λ { |o| Oj.dump(o, mode: :compat) }
15
16
 
16
- LEVENSHTEIN =-> a, b {
17
+ LEVENSHTEIN = λ { |a, b|
17
18
  mx = [(0..a.size).to_a]
18
19
 
19
20
  (1..b.size).each do |j|
@@ -42,6 +43,7 @@ module Immanence
42
43
  body = O[body]
43
44
 
44
45
  options.reverse_merge!({ status: 200 })
46
+
45
47
  headers.reverse_merge!({
46
48
  "Content-Type" => "text/json",
47
49
  "Content-Length" => ("#{body.size}" rescue "0")
@@ -54,34 +56,40 @@ module Immanence
54
56
  meta_def(conjugate(verb, path)) { instance_eval &blk }
55
57
  end
56
58
 
57
- def conjugate(verb, path)
59
+ def call(e)
60
+ @request = Request.new e["REQUEST_METHOD"].downcase, e["PATH_INFO"], I[e["rack.input"].read]
61
+ @params = ascertain receiver, @request.path
62
+
63
+ send receiver
64
+ rescue => ε
65
+ # [...] from a problem to the accidents that condition and resolve it.
66
+ self >> { error: ε }
67
+ end
68
+
69
+ private
70
+
71
+ def conjugate(verb, path) # :nodoc:
58
72
  "immanent_#{verb}_#{path}"
59
73
  end
60
74
 
75
+ # @return [Hash] Hash of request parameters
61
76
  def ascertain(method, path)
62
- method.to_s.gsub(/immanent_\w*_/, "").
63
- split("/")[1..-1].
64
- zip(path.split("/")[1..-1]).
65
- map { |x, y|
66
- { x[1..-1] => y } if x[0] == ":"
67
- }.compact.
68
- reduce({}, :merge).
69
- deep_symbolize_keys
70
- end
77
+ [method.to_s.gsub(/immanent_\w*_/, ""), path].
71
78
 
72
- def receiver
73
- methods.grep(/immanent_/).map { |method|
74
- { method: method, score: LEVENSHTEIN[method, conjugate(@request.verb, @request.path)] }
75
- }.min_by { |x| x[:score] }[:method]
76
- end
79
+ map { |path| path.split("/")[1..-1] }.
80
+ let { |x, y| x.zip(y) }.
81
+ select { |x, y| x[0] == ":" }.
82
+ map { |x, y| { x[1..-1] => y } }.
77
83
 
78
- def call(e)
79
- @request = Request.new e["REQUEST_METHOD"].downcase, e["PATH_INFO"], I[e["rack.input"].read]
80
- @params = ascertain receiver, @request.path
84
+ reduce({}, :merge).
85
+ deep_symbolize_keys
86
+ end
81
87
 
82
- send receiver
83
- rescue
84
- self >> { error: PROBLEM }
88
+ # @return [String] most likely candidate method to invoke based on incoming route
89
+ def receiver
90
+ @receiver ||= methods.grep(/immanent_/).map { |method|
91
+ { method: method, Δ: LEVENSHTEIN[method, conjugate(@request.verb, @request.path)] }
92
+ }.min_by { |x| x[:Δ] }[:method]
85
93
  end
86
94
  end
87
95
  end
@@ -1,3 +1,3 @@
1
1
  module Immanence
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: immanence
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - dzucconi
@@ -93,6 +93,7 @@ files:
93
93
  - Rakefile
94
94
  - immanence.gemspec
95
95
  - lib/core_ext/hash.rb
96
+ - lib/core_ext/kernel.rb
96
97
  - lib/core_ext/object.rb
97
98
  - lib/immanence.rb
98
99
  - lib/immanence/version.rb