實用的rubygems


#1

最近給自己一個目標,就是把過去所用的,好用的Gems
介紹一下。

文章嘗試多加截圖
跟建立一些簡單的Code Demo來示,
使用跟設定也只把重要的功能列出(絕不是懶哦。。。),
最後把Gem的功能盡量簡潔寫在標題。

現在寫了大約十篇左右,目標是二十篇。
希望大家能多給意見。


#2

我順便列我常用的好了,你要的話也可以拿去研究並拉去詳細介紹?其實我用的東西算少的,且大概都沒有 view 系列(因為都自幹惹)& gem 對我來說是雙面刃,我知道好用方便,但很多時候很難改不如自己寫,且會讓人怠惰就是 … 再來就是安全性 / 是否崩潰的問題了,對方設計不良或考慮不周全用了可能會中招,所以很多東西我都會額外寫過就是|||,除非有必要性,否則不應該不了解就隨意地加入系統之中|||

redis / redic,前者方便後者效能考量,Redis 都不知道你該去額外練了|||,and 這兩套都可以接 SSDB,但只能用 call 這個 method 去呼叫(最原生底層的 method,且很多指令不另外包裝),其實還有一套 hiredis 記得是這兩套的底層,不過不好用略過|||

will_paginate / devise / dalli / cancancan / grape / doorkeeper / recaptcha,這些應該可打好 80% 系統需求才是,每個都可以寫一長篇文了 …

paperclip / wkhtmltoimage-binary / wkhtmltopdf-binary / gravatar_image_tag / rqrcode,媒體系列?

(!)ar-octopus / base58,輔助系列,其中 Base58 很好用,但一般人只知道 Base64 唄,Octopus 可以讓 Rails 支援多 DB 但會有 connection 數過高的問題,目前還在想辦法解所以標驚嘆號

rest-client / (!)nokogiri / (x)curl / (x)savon,串接 API 大概會用這些,不過這邊有趣的是 … 你可能這些都不需要,RestClient 一直都滿穩的,雖然有時還會出包,最穩的其實還是 Ruby 內建的 HTTP 或是 call system,但不是很方便,nokogiri 有時比不上 regex (match / scan),很多時候自己過濾算了,且速度差可以超過百倍,而 curl 之前用很兇,直到 multi-thread 崩潰光光後就不信任它惹 Orz"(因為他會編譯使用 libcurl,但 multi-thread 長時間使用會隨機噴 kernel error 導致整個 ruby process 崩潰 … ),Savon 其實一樣可以用 RestClient 取代,因為 WSDL / SOAP 底層其實就是 POST + XML body 而已,所以你可以用 Savon 錄到封包後直接用 RestClient 改寫(尤其台廠一票 M$ 系列 SOAP 亂寫的時候,很多時候還不吃 Savon 包出來的 XML 的時候|||[ demo code 都拿字串來拼 XML 是哪招,還 PHP / ASP 都這樣幹哩])

sinatra / awesome_print / pry / rufus-scheduler / god 我很喜歡這票,因為最近都在寫核心,所以這票是必備哩,Ruby 內的 Thread 管理可以用 RufusScheduler 取代會方便很多,且不怕掛點,訊息部分再配上 Ruby 原生的 Mutex / Queue 就好了,再配上 God 就可以保持維運,其餘的大都是輔助就是,不過 Sinatra 不能和 RufusScheduler 配合使用,因為 Sinatra 會有最高優先權必須獨立運作(應該說他 x 的它會砍別人的 thread … ||| 當然也很有可能 RufusScheduler 之前核心用 EventMachine 寫的,和 Sinatra 的攪在一起了,現在 RufusScheduler 核心已經完全獨立就是,但不想再嘗試了 |||)

bitmask_attributes … 省 column 的利器,尤其一堆 boolean 時,全開 column 很蠢的

我能公開的大概先這些唄?其餘的其實很多都是自己寫的但不能公開,類似 …

ActionLock 請參考這篇 http://jokercatz.blogspot.tw/2016/01/rails-memcache-lock-dalli.html

IntegerObfuscator 請參考這篇 http://jokercatz.blogspot.tw/2015/03/ruby-integer-obfuscator.html

PipeImageOpt 使用者上傳檔案,順便用 exiftool 取出所有的資訊,流程和 Paperclip 應該完全一樣,但因為有過 exiftool 所以我可以取得手機型號甚至 GPS 之類的鬼出來玩

GPGme 有一套同名的 gem 爆難用,不過 … 因為 GPG / PGP 本來就很難用 X"DD 但是可以做多簽非常方便就是,所以沒辦法(多個 RSA Public key 去簽同一個檔案,任何一組 Private key 都能解)

S3Adapter 本機不留檔的 S3 串接,通常和 GPGme / PipeImageOpt 使用,所以使用者檔案上傳檢查取得資訊後,加簽 GPG,丟到 S3 內,隔離的後台取得時 S3 內取得原文,解簽,直接 Base64 顯示於 HTML 上,流程中必須保證 server 不留檔,所以就是:分離資訊 + 加密 + 儲存的保證哩

Sos 出錯 / 警告 / 每日回報用 Telegram 單向傳訊息呼叫回給不同群組的人,Telegram 的 API 中機器人傳訊只需要一個 POST 而不需要 hook,hook 是 listener 專用的哩

大概這些唄,有問題可以發問,類似怎樣製作流程怎樣之類的,但有些東西牽扯到安全因素所以我不能提供 source code 就是 : )


#3

暫時介紹的Gem都是以輔助開發除錯為主
annotate, better_errors, letter_opener_web這些
多數在development內使用的
畢竟大部分人都會有機會用到

view層面的Gems我也不大用了
現在前端時代Rails給JSON就可以了
涉及前端的Gems,除非很方便有效
例如ajax_datatable_rails這種把search order listing paging UI一併搞好的
否則我也不打算寫了

前端或許直接寫一個Npm packages系列更好。。。(又胡亂開期票了)

Devise / CanCanCan / ActiveAdmin也打算寫一下
但因為Gems有點巨大要想想如何寫得系統些
這些Gems歴史也有些也需要看看Gems的代碼才能知道現在是怎樣運行的
加上很多人都寫過了,應該不會在近期寫出來
特別是ActiveAdmin,這東西還附上N多的Gems,認真寫的話要寫最少一個月了

你所提到的Gems我也有部分用過
特別是rufus-scheduler,滿好用的
但是它在Thread層面的東西,大型系統用了就GG了,只能在小型專案玩玩。。。
安全的話還是whenever


#4

你對 rufus-scheduler / thread 的認知應該和我相反,用 whenever => cronjob 才會出事唄 X"DD (包括 race condition 之類的問題,因為你沒解決重複 process 的問題,除非另外寫 lock),目前自己寫單一系統已經到 1x 個 thread 併行了,且用 Mutex / Queue 配就可以達到完全無縫接軌,同一支程式持續跑一年以上不掛且立即反應,不過說到底其實就是老派的 thread 幹法,以後要改 golang 也方便,之後有空再來寫篇文來描述我那些奇怪的連續技怎樣用好了 |||


#5

我想是middleware server大家的選擇未必相同吧,就是Puma VS Passenger Enterprise的問題吧
另外始終覺得不要把Web Layer跟Logic Layer的Thread混在一起

Race Conditions Rails層面我的設計功能比較單一,避免互鎖
這些問題發生的還是數據庫層面比較多,為了省時管理數據庫,各種應用都寫在同一個數據庫內

不過Threading還是一件很麻煩的東西,可以不理盡量不理
現在都在研究Elixir了,它的concurrency model好像比較簡單

Golang也是挺不錯,但我還是喜歡functional programming哦


#6

沒,所以對我而言你只有 web 層而沒有其他層去處理額外事物,給你一個奇怪的額外需求,做一個聊天室,用 websocket 來寫,支援整點報時 / 投票 / 私聊功能,取得上線人數之類的,進階一點,即時對話機器人,寫一個博弈系統,類似私開群組內的撲克牌系統,莊主需要有自己的 runner(不可能等你一分鐘的 cronjob …),系統還要即時廣播更新公告和目前所得最高的玩家,比賽現況,你會知道我的意思的

anyway 這才是我所謂的 kernel 層就是了,所以沒有 Rails 時,你還剩下什麼呢?


#7

我想我明白你的意思
在我的世界內RoR是一件工具

我自己很喜歡RoR
但不會使用RoR應付所有場合

處理高流量的事情時還可以使用其他有優勢的架框跟程式語言
例如Java,Scala,NodeJS那些
以現在流行微服務形式不就可以嗎?

能改善Kernel層面的問題當然好
RoR層面對我而言就是處理Web層面的東西
倘若不是Web層面的,坦白說,我覺得RoR未必是一個很好的選擇

跟你討論我覺得很有趣哦
很久沒有跟人談這些了。。。


#8

Elixir 其實我研究完了,我知道他很好,Phoenix 不錯,但其餘資源還是不夠多,選 Golang 是因為團隊與未來專案發展,因為不想把同一個專案塞太多語言進去,且能 cross compiler 還是好用點能幫助 CI 之類的鬼,以系統而言應該單純拆短板而非全部改用,因為開發動能還是要有才是,所以目前考慮把最吃效能的都用 Golang 改寫,其餘保持用 Ruby / Rails 增加彈性與開發動能之類的

嘛,我只是這邊的 NPC 唄,歡迎來找我聊哈哈

我說 Golang 改寫的部分就是你說的 microservices 唄,所以目前一個專案通常都四個以上了唄,類似 API / 維運之類的能拆出去就拆出去了,且都最高量快取狀態,畢竟都開始有效能需求了,有的沒的


#9

Golang也有些日子了,資源比較多挺正常的
上手感覺也挺好寫
就是編程風格走imperative路綫
感覺處理複雜一點的東西未必能做到十分簡潔(文青藝術家語氣)
但效能及生產力而然確實不錯

Functional Programming對大多數人來說還是很可怕,要自己踩坑
參考也不多,幸好以前大學裏諗了functional programming
那年頭諗得死死的東西竟然有用(!)
不然自己慢慢學也是挺麻煩
另外Phoenix Channel比Rails Actioncable好太多了
處理實時的東西感覺挺美妙

Threading Model Process Model這些原本也有想過寫一下
但一來擔心寫得不夠好,二來害怕太深入把人嚇跑
最後還是沒有動筆


#10

其實對我而言每個公司都以自己的文化,有人的地方就有江湖,誰主導佔很重要的程度,選擇語言沒有對錯,每個也都有自己的強項就是,然而符合需求能做出會動的東西,符合專案期望比任何東西都還來得重要就是

面子不能當飯吃,所以很多時候不要死撐(這是對我自己說的哈哈),所以真的有需要,還是會選你說的 Elixir,我說的 Golang,甚至是 Crystal ( 其實我心中最愛這個 ) 或是 Python,最差非不得已,還是會選 Java 唄

畢竟不能動的東西包裝得再好也是不堪用的 … 一但走錯方向, Java 也會寫輸 Ruby,方向正確的話 Ruby 也能贏 Java 哩 …(單純當年我把 Java 練得不錯所以拿來做比喻 X"D 回想起來當年寫的方式錯得離譜就是哈哈


#11

對,正如Linus所說Talk is cheap. Show me the code.
搞Kernel層面也好,搞其他語言也好
只要能做出成品出來也是正確的
沒有必要執著於某種技術

Elixir跟Golang我覺得都是同樣很不錯
Crystal聽過很多Rubyists讚過,但我自己沒有認真看過不清楚

Java是很規舉的東西,現世代而然嘮叨了一些。跟NodeJS什麼百家爭鳴完完全全是個對比。
而Android的實作簡直是反面教材,把原本就嘮叨的Java變得更嘮叨更難看XD。
但Concurrency跟Data Structures都做得很不錯。

有個人叫王垠寫了篇文章為Java說話也挺有趣。
http://www.yinwang.org/blog-cn/2016/01/18/java


#12

Java 到後面你看到 goto 會想吐的,且一票不純正血統的 OOP 寫法,C# 比起 Java … OOP 純正很多,雖然是驢背上的雷射槍哈哈哈 …

其實近年我的 coding style 越來越接近 C 了 … 把 Ruby 寫成 C 還滿有趣的就是,沒有物件只有純粹的包裝,一個功能做一件事情,必要還是保留 OOP 的方便性,有的沒的


#13

Java很多類近Goto的功能Break加Label什麼我很少用盡可能以Recursion取代。。。
C#也是有趣,很多功能很方便,get set那些比Java用Eclipse自動生產出來方便太多!但只能在Windows內運行是個痛點。。。已經很久沒碰Windows了orz
OOP反而不是大問題,Java跟C#同樣是前人踩坑太多,有問題找找還是有很多Hack的方法

C寫法不是問題,但太複雜的系統除非文檔寫得很完整
否則會被其他人咒罵哦。。。


#14

比起 will_paginate,更推廌 kaminari ~


#15

對呀
正在寫kaminari也寫了一半了
不過兩者其實也沒有什麼分別
不知為什麼kaminari比較熱門一些


#16

兩者其實完全一樣,都是過 ORM 層 … 然後 scope 包裝不太一樣罷了,對我而言單純 will_paginate 是簡單方便且貼近 SQL 的好選擇,因為 code 很簡單也比較好改( 尤其有異常複雜的 raw SQL 的需求時 … 很多時候取 count 和實際分頁是完全不同的語法的,類似 JOIN / UNION 後之類的 ),不過也或許是我懶得改就是了

anyway 一般使用下兩個同值性太高的,然而其實 NoSQL 支援是另外一個比較大的議題,否則選擇哪個其實沒差就是,這篇可以多提一些,然後累死本篇的作者? X"DD

(其實 … will_paginate 會改的話一下就能支援 NoSQL ||| 因為它的 code 太簡單了 Orz" 甚至自產 Array 或是你想搞啥都行,不一定要過 ORM … 內部單純就是一個改寫過的 Array 在 each 而已 |||,但我不願意太多人用它,這樣我沒東西能說嘴沒飯吃怎麼辦哈哈哈)

每個程式語言都是一個派系,每個派系有多個門派,門派內都有自己的宗師,宗師下都有自己宣揚的東西,而門生可以選擇自己的宗師,將學到的東西組合成自己的武器庫,達到一樣的目的:『有人的地方就有江湖』


#17

nosql這個題目挺有趣
寫文字還算是容易,最大問題還是弄個示例作解釋
所以還是看時間吧

kaminari也可以支援Array的吧
kaminari跟will_paginate,我一直以為是差不多人的在搞XD

最近又在搞Go,時間真的太不好用了lll