asset_ram 1.0.0 → 1.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: af7a1812a96587aa5579767e82758e5b898b554dd28ef0c107c1f523166fa7c8
4
- data.tar.gz: ecc5d98ecc9c2fb65589d96068bd71320e0a6844881e8ec1f511061367aef973
3
+ metadata.gz: e51caa4c493e188fe6522e16c6473c7ff3c723a8afb5926ea85353ad30e675ab
4
+ data.tar.gz: 66c580f13e0eea34e2e27e25b38ebd1c567e37e604999247dec453418ecaeacb
5
5
  SHA512:
6
- metadata.gz: e7df956fa67fa0900285f570501e6d6dea99744394e9a8ef9824f08c12008a9cf68373faa27216017a7b43ed4ab6bee33295f9d3976cc1f1d56091e8839ce462
7
- data.tar.gz: cf583732e4974af18fab12dc9ee31bde5ae1f963fe842850bd0e5d6aace773eb99bd762eccaae12e1a7a3def93b69eb75c8eabf62f0bd95216e2a8a162dbbe9d
6
+ metadata.gz: b3c0b278d8a39ca23a0cd87cc640793572309f15c61c22eea267cec3ef40b77899c883d35947ac00589d645a5e808c9836861c9f760b3f8badb9e8c4a5902b77
7
+ data.tar.gz: 99dd95d7025ea7159c867559b21bcf05051cfc15449cffb1a91d70f71252901b8c6589218d0de6f922b1731260eccb9b83a3dc749e5f39884cedd67a6d2cf886
data/CHANGELOG.md CHANGED
@@ -1,4 +1,9 @@
1
- ## [Unreleased]
1
+ ## [1.1.0] - 2025-06-12
2
+
3
+ - Added a new, simpler API: `AssetRam.cache { ... }` as the preferred way to cache asset computations in views. The legacy `AssetRam::Helper.cache` API is still supported for compatibility.
4
+ - Improved documentation to highlight the new API and update usage examples.
5
+ - Added comprehensive RSpec tests for caching behavior, keying, and environment variable handling.
6
+
2
7
 
3
8
  ## [0.1.0] - 2021-09-25
4
9
 
data/Gemfile.lock ADDED
@@ -0,0 +1,35 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ asset_ram (1.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.6.2)
10
+ rake (13.3.0)
11
+ rspec (3.13.1)
12
+ rspec-core (~> 3.13.0)
13
+ rspec-expectations (~> 3.13.0)
14
+ rspec-mocks (~> 3.13.0)
15
+ rspec-core (3.13.4)
16
+ rspec-support (~> 3.13.0)
17
+ rspec-expectations (3.13.5)
18
+ diff-lcs (>= 1.2.0, < 2.0)
19
+ rspec-support (~> 3.13.0)
20
+ rspec-mocks (3.13.5)
21
+ diff-lcs (>= 1.2.0, < 2.0)
22
+ rspec-support (~> 3.13.0)
23
+ rspec-support (3.13.4)
24
+
25
+ PLATFORMS
26
+ arm64-darwin-24
27
+ ruby
28
+
29
+ DEPENDENCIES
30
+ asset_ram!
31
+ rake (~> 13.0)
32
+ rspec (~> 3.0)
33
+
34
+ BUNDLED WITH
35
+ 2.6.9
data/README.md CHANGED
@@ -1,215 +1,111 @@
1
1
  # AssetRam
2
2
 
3
- ## Tests in Production: allocation savings comes from avoiding certain rendering
3
+ **Rails 7 update: I measured a 35% reduction in allocations.** I tested
4
+ [my app's home page](https://www.public.law) in production:
4
5
 
5
- Here's where the savings come from:
6
+ * Rails 7.0.6
7
+ * Ruby 3.2.2
8
+ * Sprockets v3 and v4
9
+ * JE_MALLOC
10
+ * `--enable-yjit`
6
11
 
7
- ```ruby
8
- = AssetRam::Helper.cache { render 'footer' }
9
- ```
10
-
11
- My site's footer is static except for the asset links to e.g. social media icons.
12
+ The page is simple with only five images. If you have more, you'll get
13
+ an even bigger boost:
12
14
 
15
+ <img src="https://github.com/dogweather/asset_ram/raw/master/test-data.png" alt="Test Data" style="width: 70%;">
13
16
 
14
- ### Production comparison test #1: https://texas.public.law/statutes/tex._fam._code_section_1.001
17
+ The savings come from avoiding asset calculations. The app is faster, too.
18
+ But it's hard for me to measure precisely: enabling AssetRam, this page time
19
+ goes down from ~9ms to ~6ms.
15
20
 
16
- * 17% fewer allocations (5315 vs. 6414)
17
- * 1,099 allocations saved by simply not re-rendering the footer views.
18
- * 7ms slower
19
21
 
22
+ > [!TIP]
23
+ > Set env var `ASSET_RAM_DISABLE` to do this comparison in your own app.
20
24
 
21
- ```
22
- 2021-09-26T18:14:29.928482+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Started GET "/statutes/tex._fam._code_section_1.001" for 172.70.45.212 at 2021-09-26 18:14:29 +0000
23
- 2021-09-26T18:14:29.929520+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Processing by StatutesController#show as HTML
24
- 2021-09-26T18:14:29.929537+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Parameters: {"compilation"=>"statutes", "id"=>"tex._fam._code_section_1.001"}
25
- 2021-09-26T18:14:29.933509+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Statute Load (1.4ms) SELECT "statutes".* FROM "statutes" WHERE (LOWER(citation) = 'tex. fam. code section 1.001')
26
- 2021-09-26T18:14:29.933849+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] ↳ app/models/statute.rb:491:in `find_by_cite_case_insensitive'
27
- 2021-09-26T18:14:29.937540+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Publication Load (1.1ms) SELECT "publications".* FROM "publications" WHERE "publications"."jurisdiction_id" = $1 AND "publications"."compilation_slug" = $2 LIMIT $3 [["jurisdiction_id", 206], ["compilation_slug", "statutes"], ["LIMIT", 1]]
28
- 2021-09-26T18:14:29.937842+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] ↳ app/controllers/statutes_controller.rb:303:in `publication'
29
- 2021-09-26T18:14:29.938542+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Rendering layout layouts/application.haml
30
- 2021-09-26T18:14:29.938577+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Rendering statutes/leaf_node.haml within layouts/application
31
- 2021-09-26T18:14:29.939858+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Rendered statutes/leaf_node.haml within layouts/application (Duration: 1.2ms | Allocations: 149)
32
- 2021-09-26T18:14:29.940074+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Rendered application/_description.haml (Duration: 0.0ms | Allocations: 10)
33
- 2021-09-26T18:14:29.940669+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Rendered application/_favicon.haml (Duration: 0.4ms | Allocations: 303)
34
- 2021-09-26T18:14:29.940924+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Rendered application/_structured_data_website.haml (Duration: 0.0ms | Allocations: 11)
35
- 2021-09-26T18:14:29.941028+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Rendered application/_structured_data_organization.haml (Duration: 0.0ms | Allocations: 11)
36
- 2021-09-26T18:14:29.941086+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Rendered application/_html_head.haml (Duration: 1.1ms | Allocations: 709)
37
- 2021-09-26T18:14:29.942826+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Statute Load (1.1ms) SELECT "statutes".* FROM "statutes" WHERE "statutes"."id" = $1 LIMIT $2 [["id", 88374639], ["LIMIT", 1]]
38
- 2021-09-26T18:14:29.943230+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] ↳ app/presenters/statute_presenter.rb:149:in `parent'
39
- 2021-09-26T18:14:29.943596+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Rendered application/_body_tag.erb (Duration: 2.4ms | Allocations: 764)
40
- 2021-09-26T18:14:29.944141+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Rendered application/_small_search_form.haml (Duration: 0.2ms | Allocations: 105)
41
- 2021-09-26T18:14:29.944440+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Rendered application/_top_nav_bar.haml (Duration: 0.8ms | Allocations: 453)
42
- 2021-09-26T18:14:29.944876+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Rendered application/_breadcrumbs.haml (Duration: 0.3ms | Allocations: 397)
43
- 2021-09-26T18:14:29.945012+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Rendered application/_devise_alerts.haml (Duration: 0.1ms | Allocations: 25)
44
- 2021-09-26T18:14:29.945171+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Rendered application/_citation.haml (Duration: 0.0ms | Allocations: 27)
45
- 2021-09-26T18:14:29.945283+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Rendered application/_search_mark_toggle.haml (Duration: 0.0ms | Allocations: 13)
46
- 2021-09-26T18:14:29.945498+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Rendered application/_ads.haml (Duration: 0.2ms | Allocations: 76)
47
- 2021-09-26T18:14:29.945537+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Rendered application/_right_side_bar.haml (Duration: 0.5ms | Allocations: 296)
48
- 2021-09-26T18:14:29.946102+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Rendered application/_footer_for_screen.haml (Duration: 0.4ms | Allocations: 524)
49
- 2021-09-26T18:14:29.946243+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Rendered application/_footer_for_print.haml (Duration: 0.1ms | Allocations: 30)
50
- 2021-09-26T18:14:29.946328+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Rendered application/_footer.haml (Duration: 0.7ms | Allocations: 677)
51
- 2021-09-26T18:14:29.946526+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Rendered application/_analytics.haml (Duration: 0.0ms | Allocations: 14)
52
- 2021-09-26T18:14:29.946609+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Rendered application/_closing_body_tag.erb (Duration: 0.0ms | Allocations: 9)
53
- 2021-09-26T18:14:29.946646+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Rendered layout layouts/application.haml (Duration: 8.1ms | Allocations: 4132)
54
- 2021-09-26T18:14:29.946815+00:00 app[web.1]: [07e1adff-5df8-43d3-aab4-0e1d6b56b001] Completed 200 OK in 17ms (Views: 7.3ms | ActiveRecord: 3.7ms | Elasticsearch: 0.0ms | Allocations: 6414)
55
- ```
56
25
 
57
- ```
58
- 2021-09-26T18:21:26.654003+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] Started GET "/statutes/tex._fam._code_section_1.001" for 172.70.45.202 at 2021-09-26 18:21:26 +0000
59
- 2021-09-26T18:21:26.656935+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] Processing by StatutesController#show as HTML
60
- 2021-09-26T18:21:26.656978+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] Parameters: {"compilation"=>"statutes", "id"=>"tex._fam._code_section_1.001"}
61
- 2021-09-26T18:21:26.661787+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] Statute Load (1.5ms) SELECT "statutes".* FROM "statutes" WHERE (LOWER(citation) = 'tex. fam. code section 1.001')
62
- 2021-09-26T18:21:26.662597+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] ↳ app/models/statute.rb:491:in `find_by_cite_case_insensitive'
63
- 2021-09-26T18:21:26.670170+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] Publication Load (1.3ms) SELECT "publications".* FROM "publications" WHERE "publications"."jurisdiction_id" = $1 AND "publications"."compilation_slug" = $2 LIMIT $3 [["jurisdiction_id", 206], ["compilation_slug", "statutes"], ["LIMIT", 1]]
64
- 2021-09-26T18:21:26.670808+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] ↳ app/controllers/statutes_controller.rb:303:in `publication'
65
- 2021-09-26T18:21:26.671936+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] Rendering layout layouts/application.haml
66
- 2021-09-26T18:21:26.671990+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] Rendering statutes/leaf_node.haml within layouts/application
67
- 2021-09-26T18:21:26.676444+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] Rendered statutes/leaf_node.haml within layouts/application (Duration: 1.8ms | Allocations: 149)
68
- 2021-09-26T18:21:26.676446+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] Rendered application/_description.haml (Duration: 0.1ms | Allocations: 10)
69
- 2021-09-26T18:21:26.676446+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] Rendered application/_favicon.haml (Duration: 0.5ms | Allocations: 247)
70
- 2021-09-26T18:21:26.676446+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] Rendered application/_structured_data_website.haml (Duration: 0.0ms | Allocations: 11)
71
- 2021-09-26T18:21:26.676447+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] Rendered application/_structured_data_organization.haml (Duration: 0.0ms | Allocations: 11)
72
- 2021-09-26T18:21:26.676447+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] Rendered application/_html_head.haml (Duration: 1.4ms | Allocations: 591)
73
- 2021-09-26T18:21:26.677699+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] Statute Load (1.3ms) SELECT "statutes".* FROM "statutes" WHERE "statutes"."id" = $1 LIMIT $2 [["id", 88374639], ["LIMIT", 1]]
74
- 2021-09-26T18:21:26.678321+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] ↳ app/presenters/statute_presenter.rb:149:in `parent'
75
- 2021-09-26T18:21:26.678955+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] Rendered application/_body_tag.erb (Duration: 3.4ms | Allocations: 764)
76
- 2021-09-26T18:21:26.679660+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] Rendered application/_top_nav_bar.haml (Duration: 0.6ms | Allocations: 264)
77
- 2021-09-26T18:21:26.680105+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] Rendered application/_breadcrumbs.haml (Duration: 0.3ms | Allocations: 397)
78
- 2021-09-26T18:21:26.680279+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] Rendered application/_devise_alerts.haml (Duration: 0.1ms | Allocations: 25)
79
- 2021-09-26T18:21:26.680500+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] Rendered application/_citation.haml (Duration: 0.1ms | Allocations: 28)
80
- 2021-09-26T18:21:26.680632+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] Rendered application/_search_mark_toggle.haml (Duration: 0.0ms | Allocations: 13)
81
- 2021-09-26T18:21:26.680935+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] Rendered application/_ads.haml (Duration: 0.2ms | Allocations: 77)
82
- 2021-09-26T18:21:26.680981+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] Rendered application/_right_side_bar.haml (Duration: 0.6ms | Allocations: 298)
83
- 2021-09-26T18:21:26.681199+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] Rendered application/_analytics.haml (Duration: 0.1ms | Allocations: 14)
84
- 2021-09-26T18:21:26.681307+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] Rendered application/_closing_body_tag.erb (Duration: 0.0ms | Allocations: 9)
85
- 2021-09-26T18:21:26.681357+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] Rendered layout layouts/application.haml (Duration: 9.4ms | Allocations: 3040)
86
- 2021-09-26T18:21:26.681614+00:00 app[web.1]: [2058c55d-fc7f-4914-ac65-94a7862f1df1] Completed 200 OK in 24ms (Views: 8.6ms | ActiveRecord: 4.1ms | Elasticsearch: 0.0ms | Allocations: 5315)
87
- ```
88
-
89
-
90
- ### Production comparison test #2: https://texas.public.law/statutes/tex._fam._code_section_1.101
26
+ ## Installation
91
27
 
92
- * 17% fewer Allocations (5306 vs. 6407)
93
- * 1,101 allocations saved only by not rendering the footer views.
94
- * 1ms slower
28
+ Add this line to your application's Gemfile:
95
29
 
96
- ```
97
- 2021-09-26T18:01:39.440294+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] Started GET "/statutes/tex._fam._code_section_1.101" for 172.70.45.216 at 2021-09-26 18:01:39 +0000
98
- 2021-09-26T18:01:39.441510+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] Processing by StatutesController#show as HTML
99
- 2021-09-26T18:01:39.441555+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] Parameters: {"compilation"=>"statutes", "id"=>"tex._fam._code_section_1.101"}
100
- 2021-09-26T18:01:39.445556+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] Statute Load (1.4ms) SELECT "statutes".* FROM "statutes" WHERE (LOWER(citation) = 'tex. fam. code section 1.101')
101
- 2021-09-26T18:01:39.445960+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] ↳ app/models/statute.rb:491:in `find_by_cite_case_insensitive'
102
- 2021-09-26T18:01:39.450228+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] Publication Load (1.2ms) SELECT "publications".* FROM "publications" WHERE "publications"."jurisdiction_id" = $1 AND "publications"."compilation_slug" = $2 LIMIT $3 [["jurisdiction_id", 206], ["compilation_slug", "statutes"], ["LIMIT", 1]]
103
- 2021-09-26T18:01:39.450595+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] ↳ app/controllers/statutes_controller.rb:303:in `publication'
104
- 2021-09-26T18:01:39.451536+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] Rendering layout layouts/application.haml
105
- 2021-09-26T18:01:39.451577+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] Rendering statutes/leaf_node.haml within layouts/application
106
- 2021-09-26T18:01:39.453102+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] Rendered statutes/leaf_node.haml within layouts/application (Duration: 1.5ms | Allocations: 149)
107
- 2021-09-26T18:01:39.453319+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] Rendered application/_description.haml (Duration: 0.0ms | Allocations: 10)
108
- 2021-09-26T18:01:39.454083+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] Rendered application/_favicon.haml (Duration: 0.6ms | Allocations: 247)
109
- 2021-09-26T18:01:39.454484+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] Rendered application/_structured_data_website.haml (Duration: 0.1ms | Allocations: 11)
110
- 2021-09-26T18:01:39.454638+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] Rendered application/_structured_data_organization.haml (Duration: 0.0ms | Allocations: 11)
111
- 2021-09-26T18:01:39.454743+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] Rendered application/_html_head.haml (Duration: 1.5ms | Allocations: 591)
112
- 2021-09-26T18:01:39.456713+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] Statute Load (1.1ms) SELECT "statutes".* FROM "statutes" WHERE "statutes"."id" = $1 LIMIT $2 [["id", 88374639], ["LIMIT", 1]]
113
- 2021-09-26T18:01:39.457251+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] ↳ app/presenters/statute_presenter.rb:149:in `parent'
114
- 2021-09-26T18:01:39.457918+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] Rendered application/_body_tag.erb (Duration: 3.0ms | Allocations: 764)
115
- 2021-09-26T18:01:39.458795+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] Rendered application/_top_nav_bar.haml (Duration: 0.7ms | Allocations: 264)
116
- 2021-09-26T18:01:39.459195+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] Rendered application/_breadcrumbs.haml (Duration: 0.3ms | Allocations: 397)
117
- 2021-09-26T18:01:39.459348+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] Rendered application/_devise_alerts.haml (Duration: 0.1ms | Allocations: 25)
118
- 2021-09-26T18:01:39.459532+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] Rendered application/_citation.haml (Duration: 0.1ms | Allocations: 27)
119
- 2021-09-26T18:01:39.459629+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] Rendered application/_search_mark_toggle.haml (Duration: 0.0ms | Allocations: 13)
120
- 2021-09-26T18:01:39.459883+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] Rendered application/_ads.haml (Duration: 0.2ms | Allocations: 76)
121
- 2021-09-26T18:01:39.459936+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] Rendered application/_right_side_bar.haml (Duration: 0.5ms | Allocations: 296)
122
- 2021-09-26T18:01:39.460068+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] Rendered application/_analytics.haml (Duration: 0.0ms | Allocations: 14)
123
- 2021-09-26T18:01:39.460168+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] Rendered application/_closing_body_tag.erb (Duration: 0.0ms | Allocations: 9)
124
- 2021-09-26T18:01:39.460207+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] Rendered layout layouts/application.haml (Duration: 8.6ms | Allocations: 3038)
125
- 2021-09-26T18:01:39.460447+00:00 app[web.1]: [b7aafc2c-103a-4800-ad5d-ec3a433bbf58] Completed 200 OK in 19ms (Views: 8.0ms | ActiveRecord: 3.6ms | Elasticsearch: 0.0ms | Allocations: 5306)
30
+ ```ruby
31
+ gem 'asset_ram'
126
32
  ```
127
33
 
34
+ And then execute:
35
+
128
36
  ```
129
- 2021-09-26T18:06:54.091909+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Started GET "/statutes/tex._fam._code_section_1.101" for 172.70.45.192 at 2021-09-26 18:06:54 +0000
130
- 2021-09-26T18:06:54.093016+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Processing by StatutesController#show as HTML
131
- 2021-09-26T18:06:54.093035+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Parameters: {"compilation"=>"statutes", "id"=>"tex._fam._code_section_1.101"}
132
- 2021-09-26T18:06:54.096923+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Statute Load (1.4ms) SELECT "statutes".* FROM "statutes" WHERE (LOWER(citation) = 'tex. fam. code section 1.101')
133
- 2021-09-26T18:06:54.097253+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] ↳ app/models/statute.rb:491:in `find_by_cite_case_insensitive'
134
- 2021-09-26T18:06:54.101086+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Publication Load (1.1ms) SELECT "publications".* FROM "publications" WHERE "publications"."jurisdiction_id" = $1 AND "publications"."compilation_slug" = $2 LIMIT $3 [["jurisdiction_id", 206], ["compilation_slug", "statutes"], ["LIMIT", 1]]
135
- 2021-09-26T18:06:54.101391+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] ↳ app/controllers/statutes_controller.rb:303:in `publication'
136
- 2021-09-26T18:06:54.102192+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Rendering layout layouts/application.haml
137
- 2021-09-26T18:06:54.102243+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Rendering statutes/leaf_node.haml within layouts/application
138
- 2021-09-26T18:06:54.103670+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Rendered statutes/leaf_node.haml within layouts/application (Duration: 1.4ms | Allocations: 150)
139
- 2021-09-26T18:06:54.103856+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Rendered application/_description.haml (Duration: 0.0ms | Allocations: 10)
140
- 2021-09-26T18:06:54.104549+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Rendered application/_favicon.haml (Duration: 0.4ms | Allocations: 303)
141
- 2021-09-26T18:06:54.104780+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Rendered application/_structured_data_website.haml (Duration: 0.0ms | Allocations: 11)
142
- 2021-09-26T18:06:54.104865+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Rendered application/_structured_data_organization.haml (Duration: 0.0ms | Allocations: 11)
143
- 2021-09-26T18:06:54.104919+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Rendered application/_html_head.haml (Duration: 1.1ms | Allocations: 709)
144
- 2021-09-26T18:06:54.106775+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Statute Load (1.2ms) SELECT "statutes".* FROM "statutes" WHERE "statutes"."id" = $1 LIMIT $2 [["id", 88374639], ["LIMIT", 1]]
145
- 2021-09-26T18:06:54.107110+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] ↳ app/presenters/statute_presenter.rb:149:in `parent'
146
- 2021-09-26T18:06:54.107499+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Rendered application/_body_tag.erb (Duration: 2.5ms | Allocations: 764)
147
- 2021-09-26T18:06:54.108000+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Rendered application/_small_search_form.haml (Duration: 0.1ms | Allocations: 105)
148
- 2021-09-26T18:06:54.108352+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Rendered application/_top_nav_bar.haml (Duration: 0.8ms | Allocations: 453)
149
- 2021-09-26T18:06:54.108794+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Rendered application/_breadcrumbs.haml (Duration: 0.3ms | Allocations: 397)
150
- 2021-09-26T18:06:54.108943+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Rendered application/_devise_alerts.haml (Duration: 0.1ms | Allocations: 25)
151
- 2021-09-26T18:06:54.109118+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Rendered application/_citation.haml (Duration: 0.0ms | Allocations: 27)
152
- 2021-09-26T18:06:54.109211+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Rendered application/_search_mark_toggle.haml (Duration: 0.0ms | Allocations: 13)
153
- 2021-09-26T18:06:54.109473+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Rendered application/_ads.haml (Duration: 0.2ms | Allocations: 76)
154
- 2021-09-26T18:06:54.109530+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Rendered application/_right_side_bar.haml (Duration: 0.5ms | Allocations: 296)
155
- 2021-09-26T18:06:54.110122+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Rendered application/_footer_for_screen.haml (Duration: 0.5ms | Allocations: 524)
156
- 2021-09-26T18:06:54.110278+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Rendered application/_footer_for_print.haml (Duration: 0.1ms | Allocations: 30)
157
- 2021-09-26T18:06:54.110321+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Rendered application/_footer.haml (Duration: 0.7ms | Allocations: 677)
158
- 2021-09-26T18:06:54.110586+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Rendered application/_analytics.haml (Duration: 0.1ms | Allocations: 14)
159
- 2021-09-26T18:06:54.110704+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Rendered application/_closing_body_tag.erb (Duration: 0.0ms | Allocations: 9)
160
- 2021-09-26T18:06:54.110745+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Rendered layout layouts/application.haml (Duration: 8.5ms | Allocations: 4133)
161
- 2021-09-26T18:06:54.110920+00:00 app[web.1]: [2888c0c9-6d62-46bf-96f7-b8507b6101d3] Completed 200 OK in 18ms (Views: 7.7ms | ActiveRecord: 3.8ms | Elasticsearch: 0.0ms | Allocations: 6407)
37
+ $ bundle install
162
38
  ```
163
39
 
164
40
 
165
-
166
41
  ## Usage
167
42
 
168
43
  Wrap every asset helper call with `#cache`, like this:
169
44
 
45
+
170
46
  ### Before
171
47
 
172
48
  ```ruby
173
49
  <%= favicon_link_tag('favicon/favicon.ico', rel: 'icon') %>
50
+ # ...
51
+ <%= javascript_include_tag('application.js') %>
52
+ ```
53
+
54
+
55
+ ### After (Preferred)
56
+
57
+ ```ruby
58
+ <%= AssetRam.cache { favicon_link_tag('favicon/favicon.ico', rel: 'icon') } %>
59
+ # ...
60
+ <%= AssetRam.cache { javascript_include_tag('application.js') } %>
174
61
  ```
175
62
 
176
- ### After
63
+ Or, for compatibility, you can still use:
177
64
 
178
65
  ```ruby
179
66
  <%= AssetRam::Helper.cache { favicon_link_tag('favicon/favicon.ico', rel: 'icon') } %>
180
67
  ```
181
68
 
182
- After booting up, a message like this will appear _once_ in the log when the asset link
183
- is generated. It shows the full cache key so we can see what it's caching. This is the line
184
- of code that, without AssetRam, would be exectued on every request.
69
+ After booting up, AssetRam sends a message like this _once_ to the log for each usage:
185
70
 
186
71
  ```
187
- Caching ["/Users/robb/src/PublicLaw/public-law-website/app/views/application/_favicon.haml", 8]
72
+ Caching ["/website/app/views/application/_favicon.haml", 8]
188
73
  ```
189
74
 
190
- I use it in my footer for social icons as well: (HAML syntax)
75
+ It outputs this when the asset link is generated. It shows the full cache key (filename
76
+ and line number)
77
+ so we can see what it's caching. This is the line of code that, without AssetRam,
78
+ would be exectued on every request.
79
+
80
+
81
+ I use it in my footer for social icons as well. I **used to** have this: (HAML syntax)
191
82
 
192
83
  ```ruby
193
- = link_to asset.cache { image_tag("social/instagram-logo.svg", alt: 'Instagram', loading: 'lazy', decoding: 'async') }, "https://www.instagram.com/law.is.code/"
194
- = link_to asset.cache { image_tag("social/facebook-logo-button.svg", alt: 'Facebook', loading: 'lazy', decoding: 'async') }, "https://www.facebook.com/PublicDotLaw"
195
- = link_to asset.cache { image_tag("social/twitter-logo-button.svg", alt: 'Twitter', loading: 'lazy', decoding: 'async') }, "https://twitter.com/law_is_code"
196
- = link_to asset.cache { image_tag("social/github-logo.svg", alt: 'Our GitHub Page', loading: 'lazy', decoding: 'async') }, "https://www.github.com/public-law/"
84
+ = link_to AssetRam.cache { image_tag("social/instagram-logo.svg", alt: 'Instagram', loading: 'lazy', decoding: 'async') }, "https://www.instagram.com/law.is.code/"
85
+ = link_to AssetRam.cache { image_tag("social/facebook-logo-button.svg", alt: 'Facebook', loading: 'lazy', decoding: 'async') }, "https://www.facebook.com/PublicDotLaw"
86
+ = link_to AssetRam.cache { image_tag("social/twitter-logo-button.svg", alt: 'Twitter', loading: 'lazy', decoding: 'async') }, "https://twitter.com/law_is_code"
87
+ = link_to AssetRam.cache { image_tag("social/github-logo.svg", alt: 'Our GitHub Page', loading: 'lazy', decoding: 'async') }, "https://www.github.com/public-law/"
197
88
  ```
198
89
 
199
90
 
91
+ But my whole footer partial is static. So now I just do this instead in my layout:
92
+
93
+ ```ruby
94
+ = AssetRam.cache { render 'footer_for_screen' }
95
+ ```
200
96
 
201
97
 
202
98
  ### In some cases, the cache key can't be inferred.
203
99
 
204
- RamCache creates the cache key automatically using the view source filename and line number.
100
+ AssetRam creates the cache key automatically using the view's source filename and line number.
205
101
  This works for most uses.
206
102
 
207
- Some of my app's views are an exception, however. It's multi-tenant and the views serve content
208
- for several sub-domains. And so the call to `#cache` allows extra key info to be passed.
209
- In my HTML HEAD view, I have a `site` variable for choosing the CSS file for the domain:
103
+ Some of my app's views are an exception, however. It's **multi-tenant** and the views serve content
104
+ for many sub-domains. To handle this, the call to `#cache` allows extra key info to be passed.
105
+ In my HTML `head` view, I already had a `site` variable for choosing the CSS file for the domain. So I reuse that as extra cache key info:
210
106
 
211
107
  ```ruby
212
- <%= AssetRam::Helper.cache(key: site) { stylesheet_link_tag("themes/#{site}", media: nil) } %>
108
+ <%= AssetRam.cache(key: site) { stylesheet_link_tag("themes/#{site}", media: nil) } %>
213
109
  ```
214
110
 
215
111
  ## Background: I was looking for ways to reduce allocations in my Rails app
@@ -217,10 +113,13 @@ In my HTML HEAD view, I have a `site` variable for choosing the CSS file for the
217
113
  In an effort to help my app run in a small 512MB virtual server, I looked through every view
218
114
  invocation in the logs. After I optimized a bunch of my code, I realized that the asset helpers
219
115
  create a relatively large amount of objects. The code is pretty complex too implying some amount
220
- of CPU overhead. Moreover, this work is done over **on every request**.
116
+ of CPU overhead. Moreover, this work is **repeated on every request**.
221
117
 
222
- These asset fingerprints are potentially re-generated on every deploy. So they can't be stored in
223
- the usual Rails cache. I realized that storing the computed paths in a simple hash (in RAM only)
118
+ These asset fingerprints are potentially re-generated on every deploy. Maybe I edit an image, but
119
+ I haven't modified any ActiveRecord models. This means that **the asset links cannot be stored in
120
+ the standard Rails cache.** (If the Rails cache had a lifetime option of, "until next boot", that would solve the problem.)
121
+
122
+ I realized that storing the computed paths in a simple hash (in RAM only)
224
123
  would be fast and never return stale data: The RAM cache goes away on a deploy/restart, which is
225
124
  when asset fingerprints could change.
226
125
 
@@ -236,29 +135,10 @@ To make it as easy as possible to use, the lib finds the view's source filename
236
135
  the code being cached. This has been working well and in production for four months in a large Rails app.
237
136
 
238
137
 
239
-
240
- ## Installation
241
-
242
- Add this line to your application's Gemfile:
243
-
244
- ```ruby
245
- gem 'asset_ram'
246
- ```
247
-
248
- And then execute:
249
-
250
- $ bundle install
251
-
252
- Or install it yourself as:
253
-
254
- $ gem install asset_ram
255
-
256
-
257
138
  ## Development
258
139
 
259
140
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
260
141
 
261
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
262
142
 
263
143
  ## License
264
144
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AssetRam
4
- VERSION = "1.0.0"
4
+ VERSION = "1.1.0"
5
5
  end
data/lib/asset_ram.rb CHANGED
@@ -5,9 +5,9 @@ require_relative "asset_ram/version"
5
5
  #
6
6
  # Use in views to cache the asset path computation.
7
7
  #
8
- # For example, in a HAML file:
8
+ # Preferred usage (since v1.1.0):
9
9
  #
10
- # = AssetRam::Helper.cache { favicon_link_tag('favicon/favicon.ico', rel: 'icon') }
10
+ # = AssetRam.cache { favicon_link_tag('favicon/favicon.ico', rel: 'icon') }
11
11
  #
12
12
  # The calculated asset paths are keyed by source file name and line number.
13
13
  # The results are stored in RAM.
@@ -15,7 +15,11 @@ require_relative "asset_ram/version"
15
15
  # Sometimes, a key is needed if the code is run in different contexts, like
16
16
  # a multi-tenant site:
17
17
  #
18
- # = AssetRam::Helper.cache(key: site) { stylesheet_link_tag("themes/#{site}", media: nil) }
18
+ # = AssetRam.cache(key: site) { stylesheet_link_tag("themes/#{site}", media: nil) }
19
+ #
20
+ # For compatibility, you can still use:
21
+ #
22
+ # = AssetRam::Helper.cache { ... }
19
23
  #
20
24
  # To test and compare if this lib actually improves performance,
21
25
  # set the ASSET_RAM_DISABLE env var and it will transparently never cache.
@@ -24,15 +28,23 @@ require_relative "asset_ram/version"
24
28
  module AssetRam
25
29
  class Error < StandardError; end
26
30
 
31
+ ##
32
+ # The simpler API: AssetRam.cache { ... }
33
+ #
34
+ def self.cache(key: '', &blk)
35
+ Helper.cache(key: key, &blk)
36
+ end
37
+
27
38
  ##
28
39
  # Our own asset helper which memoizes Rails' asset helper calls.
40
+ #
29
41
  class Helper
30
42
  @@_cache = {}
31
43
 
32
44
 
33
45
  def self.cache(key: '', &blk)
34
46
  cache_key = blk.source_location
35
- cache_key << key if key.present?
47
+ cache_key << key if !key.to_s.empty?
36
48
 
37
49
  cache_by_key(cache_key, &blk)
38
50
  end
data/test-data.png ADDED
Binary file
metadata CHANGED
@@ -1,18 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asset_ram
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
- - Robb Shecter
8
- autorequire:
7
+ - Robert Shecter
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2022-08-18 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies: []
13
- description:
14
12
  email:
15
- - robb@public.law
13
+ - robert@public.law
16
14
  executables: []
17
15
  extensions: []
18
16
  extra_rdoc_files: []
@@ -20,21 +18,21 @@ files:
20
18
  - ".rspec"
21
19
  - CHANGELOG.md
22
20
  - Gemfile
21
+ - Gemfile.lock
23
22
  - LICENSE.txt
24
23
  - README.md
25
24
  - Rakefile
26
- - asset_ram.gemspec
27
25
  - bin/console
28
26
  - bin/setup
29
27
  - lib/asset_ram.rb
30
28
  - lib/asset_ram/version.rb
31
- homepage: https://github.com/dogweather/asset_ram
29
+ - test-data.png
30
+ homepage: https://github.com/public-law/asset_ram
32
31
  licenses:
33
32
  - MIT
34
33
  metadata:
35
- homepage_uri: https://github.com/dogweather/asset_ram
36
- source_code_uri: https://github.com/dogweather/asset_ram
37
- post_install_message:
34
+ homepage_uri: https://github.com/public-law/asset_ram
35
+ source_code_uri: https://github.com/public-law/asset_ram
38
36
  rdoc_options: []
39
37
  require_paths:
40
38
  - lib
@@ -49,8 +47,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
49
47
  - !ruby/object:Gem::Version
50
48
  version: '0'
51
49
  requirements: []
52
- rubygems_version: 3.3.11
53
- signing_key:
50
+ rubygems_version: 3.6.9
54
51
  specification_version: 4
55
52
  summary: Improves Rails performance by caching asset path calculations
56
53
  test_files: []
data/asset_ram.gemspec DELETED
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "lib/asset_ram/version"
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = "asset_ram"
7
- spec.version = AssetRam::VERSION
8
- spec.authors = ["Robb Shecter"]
9
- spec.email = ["robb@public.law"]
10
-
11
- spec.summary = "Improves Rails performance by caching asset path calculations"
12
- spec.homepage = "https://github.com/dogweather/asset_ram"
13
- spec.license = "MIT"
14
- spec.required_ruby_version = ">= 2.4.0"
15
-
16
- spec.metadata["homepage_uri"] = spec.homepage
17
- spec.metadata["source_code_uri"] = "https://github.com/dogweather/asset_ram"
18
-
19
- # Specify which files should be added to the gem when it is released.
20
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
21
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
22
- `git ls-files -z`.split("\x0").reject do |f|
23
- (f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
24
- end
25
- end
26
- spec.bindir = "exe"
27
- spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
28
- spec.require_paths = ["lib"]
29
-
30
- # Uncomment to register a new dependency of your gem
31
- # spec.add_dependency "example-gem", "~> 1.0"
32
-
33
- # For more information and examples about making a new gem, checkout our
34
- # guide at: https://bundler.io/guides/creating_gem.html
35
- end