Ruby Ruby 的当务之急是推出一套 comment type hint 标准

gaicitadie · 2019年06月27日 · 最后由 jasl 回复于 2019年06月28日 · 6311 次阅读

并不需要强制的在语言层面实现静态类型,只要推出一套标准,让 ide 能推导出类型就可以了。现在开发对 ide 越来越依赖,能推导出类型太重要了。

不是已经有了,连 runtime 都有,至少 spec 的时候可以开启

Yardoc 的註釋就可以了?

表示认同,类似 python 的类型标注。

franklinyu 回复

Yardoc 貌似不能标注类的实例属性。只能标注方法的参数和返回值类型,以及变量的类型,并且变量的类型只能标在上面,不能标在句末,用起来很不灵活,标在上面有时候影响阅读代码。

Sorbet 已经搞出来了啊

jasl 回复

刚看了一下 Sorbet,侵入性太强,已经侵入到运行层面了,其实类型标注是给 IDE 看得,不需要运行时检查,在注释里写已经足够了。

这方面 php 做的最好,十几年前就有一套标准了,phpstorm 对它的支持也最强。可以标注方法的参数和返回值类型,可以标准类的实例属性(这对 laravel 的 model 非常有用),可以在句尾标注变量属性。

最最 nb 的是,可以在 laravel 模板标注变量的类型,只要在模板开头标注了,整个模板都有效,太方便了,在模板里使用 model 实例对象的时候,属性和方法可以做到 100% 的智能提示,command + 鼠标点击方法,可以 100% 的到达定义方法的地方,就连 java 的框架都做不到在模板里 100% 的智能提示,phpstorm 做到了,得益于 php 成熟的类型标注。

gaicitadie 回复

并不是,好好读读文档吧,Sorbet 是可选的静态检查 + 可选的动态检查,不要以为 extend 了一个 module 就侵入到动态了

jasl 回复

你没懂我的意思,我是说,类型标注只需要在注释层面,这样丝毫不影响运行速度,不增加运行程序的额外负担。

gaicitadie 回复

https://github.com/sorbet/sorbet/blob/master/gems/sorbet-runtime/lib/types/sig.rb#L10 说了 "不要以为 extend 了一个 module 就侵入到动态了" 看好这是一个空方法

jasl 回复

不管是不是空方法,能做到运行 0 负担吗?不要说什么可以忽略不计之类的话。对于强迫症,接受不了这种进入到运行层面的类型标注。已经影响到代码的美观了。

gaicitadie 回复

那你告诉我 sig 方法的执行时机在哪里?

signature 喊的最凶的是 clojure、elrang 这种。也有一些实现,但实际项目中用的又没多少。 clojure 这种没有对象的概念,操作的都是字段。 ruby 这种面向对象语言,操作的不是某个字段,而是类。

gaicitadie 回复

确实是运行 0 负担啊,require 进来的时候多编译一行代码而已,这点都算负担的话那就不要用 ruby 了。

jasl 回复

“extend 了一个 module”占不占用内存空间?不管它是不是运行,都污染了上下文,占用了命名空间。能保证 100% 不跟程序本身的命名冲突吗?

adamshen 回复

说的跟你是松本行弘似的,真不把自己当外人了。都引入一个 module 了,还 0 负担,睁着眼睛说瞎话。

gaicitadie 回复

你就不用杠了。。。

这个是不是有运行负担跟我问你的问题“sig 方法的执行时机在哪里?”有关,adam 正是回答了这个问题,虽然讲法不太直接。

其次,刚才说影响运行速度,现在改占内存空间了。。。如果我说占用空间约等于 0 呢?占用命名空间确实是问题,但是首先我没见过有命名模块为 T 的单字符项目,如果你用 IDE,你多半会发现默认的 IDE 的风格规则小于两个字符都会给你 Warning,其次,你告诉我 sig 影响的是实例方法还是类方法?

jasl 回复

是你自己在杠好吗?我没兴趣看你卖弄 Sorbet 的知识,因为我对它提不起丝毫的兴趣。占用内存空间就会影响运行速度,不要说约等于 0,它还是大于 0,占用命名空间已经无法接受了。我只是需要一个被 ide 识别的类型标注(注释),不要强行推销你的信仰。

gaicitadie 回复

所以你根本没理解我说的,因为答案就是 0。。。这个你不需要理解 Ruby 的实现,只需要了解 Ruby 的语法就足够解答了

另外占用内存空间会影响运行速度,说明你大学的理论课都没学好,这个我真的表示很遗憾。。。

希望你还是要好好学习一个,提高自己的姿势水平,这是坠吼滴

jasl 回复

电脑内存满了会不会变卡?你那所谓的为 0 的 Sorbet 占用的内存很可能就是压弯骆驼的最后一根稻草

如果我是楼主,我就承认自己下结论太草率了,不然就会在更多人面前暴露自己的缺陷。

你一开始说要 type hint。

好吧,Sorbet 动静也不太小,你居然不知道。作为 ruby 爱好者,你已经丢范儿了。

然后去看了一眼,估计连文档也没看,就判断出 Sorbet 是侵入型的。

好了,继续开喷,想找回场子。

结果呢?sorbet runtime 只是可选的,然后你又只能抓住 namespace 和 module 这些微不足道的点死撑。

我觉得吧。不懂并不可怕,可怕的是死要面子,失去了真正认识一件事需要的耐心。

gaicitadie 回复

首先,你听说过现代操作系统的 Prefetching 特性么。。。OS 可是为了性能可劲的往内存里塞东西啊。。。

其次,引入模块占用的内存还不够做内存对齐的,这里不占用内存,占用内存的在另一个地方(这个问题可以留给你)但是,他这段实现占用的内存,也是小到完全可以忽略的(KB 级别)

前面已经说了,代码级别的类型标注不能接受。此贴终结。

jasl 回复

另外,你说的 doc,你可能不知道 doc 里做类型标注是基于所有语言的标准做法... Ruby 当然也有啦

摘抄自 https://devhints.io/rdoc

# Foo.
#
# @example
#
#   y
#   g
#
# @param [String] param_name The xx and xx.
#
# @see http://url.com
#
# @return [true] if so
jasl 回复

没仔细看我的帖子,

1、ruby 目前没有对实例属性的的标注,rails 的 model 里面没有定义实例属性,有时候 ide 就提示不出来

2、ruby 标注变量类型,只能在变量上面增加一行,没法标注在行尾,已经影响了代码的阅读,前面我已经说了,类型标注就是给 IDE 看得,让它对 ruby 这种动态语言的智能提示更准确一些,为了实现这种智能提示,变量上面加一行注释我都会觉得影响视线,能接受 Sorbet 这种代码级别的标注?省省你的信仰吧。

gaicitadie 回复

1 RubyMine 对 Rails 的 model 和 view 做了特别处理,实际上模型的属性是从 SchemaCache 里读的

2 没看懂,也不懂为什么不能标注在行尾

最后再说你的观点,首先,我觉得可以接受,目前我关注社区的讨论没有批评的,这件事从两年前就开始了,Matz 自己做的 Soft type,还有 Sorbet,还有人在做类似 .ts.d 的方案,去年 RubyKaigi 有几场关于类型的分享,目前看 Sorbet 胜出,而且 Sorbet 的作者的背景非常的好,编译器、静态分析方向的博士,师从 Scala 的作者,同时还是 Scala 的(前)重要成员,更关键的是,Sorbet 有一个宣传点就是 Stripe 已经用这个在生产环境上很久了。

其次,为了让 IDE 更智能,并不需要标注类型,其实更多的做法是“抽象执行”,这个技术下是不需要你去标注类型的,算法可以推导,当然也有他的问题了,RubyMine 应该是在用这个技术,同时效果更好的版本 Ruby 也有核心开发在做

gaicitadie 回复

最后,每个人都可以有自己的喜好,包括 Matz 最近搞的管道操作符被社区骂惨了,但是为了反对而找理由就不好了,而且确实你提影响内存占用和性能都站不住脚,反而暴露了你基础知识薄弱。

可能话不好听,你多担待着点。

jasl 回复

爷没工夫给你抬杠,更没工夫了解你的信仰。爷现在用着 java 的 freemarker 模板的类型标注,在模板里直接跳到方法的定义,真香。

gaicitadie 回复

你开心就好

杠精。

jasl 回复

心疼你...

gaicitadie 回复

rubymine 现在就可以

lidashuang 回复

rubymine 不支持在模板里标注类型

我觉得近段时间,楼主的脾气都很大哦···错觉!?😂 😂 😂

gaicitadie 回复

类型标注只需要在注释层面 是啥意思哇 嘤嘤

jasl 回复

“抽象执行”?

stephen 回复

脾气大了好几年了。。。远早于杠精这个词的出现

jasl 回复

這個不準確,原生 rdoc並不支持這種「類 Javadoc 標籤」。

franklinyu 回复

准确的说这是 YARD,RubyMine 默认使用的注释格式

zzz6519003 回复

概念问 Wiki https://zh.wikipedia.org/wiki/%E6%8A%BD%E8%B1%A1%E9%87%8A%E4%B9%89

实际参考这个项目 https://github.com/mame/ruby-type-profiler

抽象解释(按 Wiki 的翻译法)有他自己的问题,算法复杂度很高,那个项目试验性质多半要坑

woshi gaici de laopo

rubymine 支持注释吧,mac 的话 alt + Enter 就可以简单的添加,添加以后 IDE 就可以分辨类型,然后就可以准确的 code jump。rubymine 以外的 IDE 不清楚。

# @param [User] user
# @return [User]
def test2(user)
  user.save
  user
end
heroyct 回复

Sorbet 开源后,社区贡献的工具链也开始出来了,Rails 那堆动态方法有工具来生成类型标注 https://github.com/chanzuckerberg/sorbet-rails

需要 登录 后方可回复, 如果你还没有账号请 注册新账号