Ruby语言到底前景怎么样?

大学专业并不是学的计算机,本科基础学了C语言基础教程,然后工作后由于种种原因,直接入手ruby语言。感觉ruby语言确实容易理解,毕竟我不认为我C语言…
关注者
308
被浏览
201,423
登录后你可以
不限量看优质回答私信答主深度交流精彩内容一键收藏

大约在 2017 年,我发表了 《谈谈我对 Ruby 的看法》

时隔多年,再回首看看 ruby,有了一些新的看法。

从源分析

21 世纪刚开始,rails 让 Web 带来了快速的、敏捷的实现方式。

例如,使用 ActiveRecord 无需像 java spring frameworkbean 那样,每个 POJO 都得绑定注解,或者手工 Mapping 每个 members to the field in the table of database。

再加上运行时的动态 reload,让整个 web app 能快速重载所有逻辑,继续进展开发流程。

案例

Golang - Gin

// album represents data about a record album.
type album struct {
    ID     string  `json:"id"`
    Title  string  `json:"title"`
    Artist string  `json:"artist"`
    Price  float64 `json:"price"`
}

func postAlbums(c *gin.Context) {
    var newAlbum album

    // Call BindJSON to bind the received JSON to
    // newAlbum.
    if err := c.BindJSON(&newAlbum); err != nil {
        return
    }

    // Add the new album to the slice.
    albums = append(albums, newAlbum)
    c.IndentedJSON(http.StatusCreated, newAlbum)
}

...

Example 链接: 点击查看 Gin 完整教程

Ruby - Rails

class Product < ApplicationRecord
end

p = Product.new
p.name = "Some Book"
puts p.name # "Some Book"

风格浅析

Golang 方案

优势

可维护性、迭代能力强:你的同事在接手你的代码,只要看一遍、了解一下业务就能开始工作。

  • 每个属性都有显式声明,作为 编译型语言,业务逻辑在编译过程中,能完成一轮检测,错误能够被提前发现(包括拼错、错误引用和无效调用等)。
  • 每个符号和地址(包括函数符号、属性成员地址)都能精确匹配,利于 IDE 进行索引,让有利于 code review & code analyze。
  • 没有继承,不会产生 隐藏问题,比如这个 struct 的成员变量会不会具有「二义性」,完全不用担心成员方法会不会「被多态」或者有「默认实现」。

缺点

对于注重情感人格类型的开发工程师,会因为太死板了写起来不舒服,上班不开心,影响效率

  • 人工编码时间(或可用 pb 进行自动化生成)
  • 缺乏动态注入能力,不灵活,死板,可能本来目的很明确的事情,可能要绕着来,尤其是需要到「工厂方法」和「IoC 装置」方面。

Rails 方案

优势

注重情感人格类型的员工,上班很开心,能获得很高的工作生产效率 buff,并且有兴趣进行工作任务的实施与拓展

  • 不需要到 database 里面建 Table,或者建好了 table 自动帮你读出来。
  • 全程以超音速运行敏捷开发
  • 热修复能力强,一旦遇到 bug 能马上打补丁(利用动态语言的特征)

缺点

可维护性差,后期接手的同事如果得不到良好的交接,几乎全靠猜

如果 database 的 schema 建多了,一旦员工离职,下一任员工接手的话,完全不知道:

  • 这些 table 还有用吗?
  • 哪些 field 是仍然需要的?
  • 好多 monkey-patch,当初打这个补丁到底为了解决啥问题?
  • 文档呢,文档在哪里?
  • 类型非静态,会因为动态注入,导致突然运行到这里就 莫名其妙多了个变量或方法
  • 以上动态产生的属性和方法,先别说 IDE 没有提示,连源码也看不出来

文化博弈

有时候,我们会碰到一些问题:

  • 为什么 Ruby 在国内一直流行不起来?
  • Golang / Python 很受欢迎?

向自由

西方文化比较注重个人的人权,Ruby 能放飞你的身心,让个人的人生追求得到非常充分的表达和五彩斑斓地展现。「我们不一样」,我们是我们每个人当中的自己,具有自己的个体特征和个性。只要通过自己的努力,能为企业产生效益和价值换取回报就 OK。

There's more than one way to do it ——《Perl programming motto》

向统一

P.S. 出于某些原因,我不敢写成 “砖痔”

传统儒家思想希望的是「大同」,大家都能按照统一的风格,同一行为具有制约、限制的统一表达方式。Golang 或是 Python 更能够让「大同」思想获得良好的体现,你写的逻辑,跟我写的,不管怎么写,最终几乎都会是一样的

There should be one and preferably only one obvious way to do it ——《Zen of Python》

自由之火

了解过「比特币」这类的虚拟货币的特征,它们大概都有一个特点——自由。

积极面

当你选择 Ruby 方案的时候,你便选择了自由编码,你可以用各种方式、各种手段把模块做成你想要的样子。

Ruby 确确实实在 词法 层面,解决了 Python 不利的很多场景,几乎可以想象成 the next gen of py。在享受 py 简洁基础风格的 coding,同时也能有更多方式灵活解决同一个问题。

负面

自由,可让事情变得灵活,让生活变得舒适,但走向极端的自由,像是把着没有刹车的方向盘,完全失控。

非常自由的货币,可以通过流通获得升值,当然,过度泡沫化击鼓传花的后果,可能感觉跟「传销」有点类似了。

「出来混迟早是要还的」,在使用大量 DSL 的时候,必然是选择了降低可维护的代价

以下列举一些场景

符号滥用

过度滥用 Symbol,后果导致别的同事看你的代码,会有疑惑,这些 method / member 它们在运行中会不会 nil 掉?

你的代码给维护者带来「不安全感」

class Student
# members
End

s = Student.new
s[:some_member] = ... # 又可能会 nil 掉

DSL 滥用

非显式的东西,往往带有 不确定性,判若 空穴来风

我真的不喜欢 DSL,因为一般几乎只有「外包公司」这种需要「速产」的场景,才需要这类特性,一个月交付一个网站 赚快钱 之类的。

这些东西几乎是一次性投入的,后期几乎难以维护。

ThinkPHP:

使用 D 方法M 方法 或是其它方法(这些统称 “宏” 好了),为了快速投产进行不规范的快速逻辑开发。

namespace Home\Service;
use Think\Model;
class UserService extends Model {
}

D('User') //实例化UserModel
D('User','Logic') //实例化UserLogic
D('User','Service') //实例化UserService

Rails Parameter:

s_id = params[:id]

Sinatra:

require 'sinatra'
get '/frank-says' do
  'Put this in your pipe & smoke it!'
end

时代过去了

技术更迭

首先,Web 2.0 时代早就过去了,之所以 Rails、ThinkPHP 这类的快速开发框架越来越少被使用原因,是因为 2022 年目前还有其它更好的 languages & frameworks。

其次,16 年开始 micro-service 酝酿了之后,monolith 变得越来越不利于团队合作,拆分后对于有规模的团队而言,让分工更加清晰。

再者,21 年开始,ServerLess & Web-Assembly 要开始发力了,已经有 golang、rust 等新星在这些领域逐渐强壮。

可以阅读这些文章:

以上可以让后端无缝集成到客户端里面,尤其在 边缘计算领域 将发挥极其重要作用。

所以,留给后端的机会,不是去折腾这些写 API 啦、写网页的事情了。这些东西已经没有太大价值和意义。

反而更注重的是后端工程师能如何把数据流处理好、更有效能,或者是 database 里的数据如何进行分析、还有机器学习让推送信息更精确等等。

弥留的问题

目前 ruby 似乎尚未有 全程显式 coding 的 framework。

毕竟大部分 rubyist 都偏向于 省事,自作聪明地发明一些 DSL 去解决问题,他们都喜欢:

使用更少的代码做更多的事情

但是呢,这也是导致很多国内的公司特别排斥 ruby,回到 17 年我发表的《谈谈我对 Ruby 的看法》,领导还是对这些「自作聪明」比较反感的。

DSL 的主要问题是什么呢?——隐晦

不管认同与否,都贴一下王垠的文章——《DSL 的误区》

关于「隐晦」问题,是导致这个方案能否可维护、持续迭代和持续交付的一个很重要的东西。

虽然 ruby 很多便捷,Rails 不等于 ruby,但是大体 ruby 整个圈子群体似乎都喜欢 rails 这种风格,普遍都喜欢 DSL。

然鹅:

给后人留坑、留下麻烦,不见得是一件好事。

这就是为何市场上越来越难招聘到 ruby 工程师,以及随着 golang 在丰富了标准库以后,虽然写起来不方便,但同样也能简单地解决问题。

还有 python,虽然不灵活,但是也能简洁解决问题,那么更多的人都将涌向 python。

其它的,上面在比较 golang 和 ruby 的地方已经说了一堆了,可以往上翻,文中此处就不重复了。

静态编译型的时代

随着很多人意识到了可维护性之后,越来越多的人和企业,转向了选择 静态 & 编译型 的开发工具。

毕竟,从可维护角度来看,从 DB 取出来的数据,是个可以索引到的真实的 struct,而不是一堆不确定的 HashMap 成员。

案例:Crystal - Grinite

class Book < Granite::Base
  connection mysql

  column isbn : UUID, primary: true
  column name : String
end

book = Book.new
book.name = "Moby Dick"
book.isbn # => nil
book.save
book.isbn # => RFC4122 V4 UUID string

总结

在现在这个时候,连原本写 JavaScript 都基本转向 TypeScript。

动态 语言在这个时代似乎不太吃香,毕竟开发出来的代码,都是企业的生产资料。

如果是写 个人项目,或者是一些稍微宽裕的内部项目,动态语言可以带来快速开发和灵活度的提升。

辣莫,动态 语言在哪些方面发挥比较大的作用呢?

比如数据分析,像 python 调 Tensorflow 进行数据采样进行统计分析,这些项目如果使用编译型语言,无法获得 ruby irb / python REPL 进行实时的运行时切入调试。

尤其当你从 spark / elastic search 拉到一批数据的时候,生成报表货采样分析,如果使用编译型语言的话,有些 data 会存在动态性的缺失,这个场景下要是使用 golang,那么整个流程就得重新跑了,好不容易抓到一行重要数据了又得重来。

但是呢,如果使用 ruby irb / python REPL 就能运行一行,然后 print 结果,然后继续运行下一行,然后或许动态地变更部分的逻辑代码,进行 monkey patching,然后让下一次读写能够生效新的逻辑。

所以说,脚本语言还是比较利好这些需要 “断片执行” 的使用场景和工作场合。

或者游戏开发领域,需要动态更新本地的游戏业务逻辑,升级游戏 App 本体的内部业务功能,这些都是比较有利的。

还有一些场景例如做业务流编排,需要动态重新生成编排逻辑,用脚本动态产生脚本(用魔法打败魔法),也是比较优秀的。