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

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

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

共收到 44 条回复

不是已经有了,连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

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