你可以用 FFI https://github.com/ffi/ffi
比 C 拓展 容易
同样关注
Ruby 我觉得最大的优点就是 跟直觉一致。最小惊讶设计
虽然写的很丧,这是主观的。客观的 2024 你收获满满。 希望 2025 经济好一点。
当你发现 缩进是一个很差的设计,随便一个空格就能让程序崩溃,就会发现 ruby 是个宝藏。
我用 Ruby 来写几乎所有程序,除了页面
我觉得其他语言不好用。Ruby 的内部一致性最好很符合直觉。
Ruby 很慢么?我甚至不觉得。
90% 的问题都可以解决。如果你真的遇到了性能问题,可以 C 拓展、FFI 到 C 还可以 直接 加入 Crystal 解决你觉得计算慢的地方。
整体上来说,开发速度很快。
有的需求就是混乱的。导致用代码描述的时候,会自相矛盾。 PM 的角色,本质上是一个前期逻辑过滤器。
代码的复杂性,来自于 需求衍生出来的 状态,以及状态转换。还有就是信息熵。 重构就是在不断地 逆熵的过程。
彻底失控的熵增,处理熵增的成本 > 重写 的时候,就可以认为 这项目 死了。
答案:
alias 做的事情:将方法入口名,改为 新名字,更新方法环境变量(所在类)。新名字,最后引用原始的方法。
void
rb_alias(VALUE klass, ID alias_name, ID original_name)
{
// 1)查找原始方法
// .....
orig_me = search_method(klass, original_name, &defined_class);
// 2) 继承关键信息
// .....
// 如果原始方法是 super 方法(VM_METHOD_TYPE_ZSUPER),则将 klass 设置为其父类,并将 original_name 设置为原始方法的原始 ID,然后跳转到 again 标签重新查找原始方法。
// 如果原始方法是别名方法(VM_METHOD_TYPE_ALIAS),则获取原始方法的可见性,并将 orig_me 设置为原始方法的原始方法条目。断言原始方法的类型不是别名方法,以避免无限循环。
switch (orig_me->def->type) {
case VM_METHOD_TYPE_ZSUPER:
klass = RCLASS_SUPER(klass);
original_name = orig_me->def->original_id;
visi = METHOD_ENTRY_VISI(orig_me);
goto again;
case VM_METHOD_TYPE_ALIAS:
visi = METHOD_ENTRY_VISI(orig_me);
orig_me = orig_me->def->body.alias.original_me;
VM_ASSERT(orig_me->def->type != VM_METHOD_TYPE_ALIAS);
break;
default: break;
}
// 处理特殊方法,边界
// ...... 省略
// 3)设置 方法 入口
// 调用 method_entry_set 函数在 target_klass 中为 alias_name 设置别名方法条目
// 并且设置关联属性
rb_method_entry_t *alias_me;
alias_me = method_entry_set(target_klass, alias_name, orig_me, visi, orig_me->owner);
RB_OBJ_WRITE(alias_me, &alias_me->owner, target_klass);
if (RB_TYPE_P(target_klass, T_MODULE)) {
// defined_class should not be set
}
else {
RB_OBJ_WRITE(alias_me, &alias_me->defined_class, orig_me->defined_class);
}
}
发现 sinatra 最好用,api 设计的很好
丑的不想看
不用
小作坊的方式,行得通 work 可以。
但是良好的设计,是自己有一个完整的 token 体系,openid 作为 微信小程序过来的身份信息(等同于微信上的身份证),加到当前用户的 profile 里,继续返回 token。
用户的敏感信息不应该随意存储。openid 就像指纹一样唯一,没有谁会把自己的指纹到处贴,存档。
有了拓展体系,未来你还可以接入 google、oauth、第三方、支付宝……
好的设计是这样
很有创意,很像输入法
你可以理解为
def test1(&block)
yield
end
yield 是个关键字,出现在这样的语法中,会被解析。
def <FuncName>
yield
end
而第二个例子 define_method 传入的是一个 block 参数,而 block 参数不是一个函数结构,所以没有 yield。
define_method(:test2) { | &block|
yield #if block_given?
}
这里你可以用 block.call
实现 yield 效果。
define_method(:test2) { | &block|
block.call
}
上面不确定,能否转 WebAssembly。现在确认了。 @LongLonghaoran
V1.1.0 添加 转 WebAssembly
添加一个引用:
https://ruby-china.org/topics/43776 《MRuby Devkit 一个简单的脚手架,帮助你像 Go 一样把 Ruby 编译成可执行二进制文件》
使用 MRuby 可以打包出二进制
MRuby 和 CRuby 完全不同。所以不能直接 把 Rails 转过去。
MRuby 相当于完全重新实现的 Ruby 解释器。更偏向于 C 的特点。由于没有完全的对齐 gem、bundle 等生态,所以 MRuby 的程序得单独开发。
跳出 Web,MRuby 就有使用场景了。
因为 MRuby 重新实现了 Ruby:
使用的场景:
是的。时髦有风险。
Node 能做的,Sinatra + Sequel(ORM)其实都行。我经常用这个渲染页面。
Ruby 下的 Sequel(ORM)0 BUG,实在是强。
https://dontusesystemruby.com/
也提到了安装方法
Raw SQL 遇到过错误 https://github.com/prisma/prisma/issues/21570
我以为这种 RawSQL 的 API 是软件的底层,应该先设计。结果一年多都没解决。
吹自己是次世代,我现在对 JavaScript 的东西保持怀疑。
次世代框架你也不能说它错,反正不是“现代”能用的框架。
放弃了
JRuby 对 需要本地编译的 C 拓展不友好。大多数游戏 lib 都是 C。 Truffleruby 虽然说支持 C 拓展,结果一样,跑不起来。
做一个前置的 Installer 不论是脚本,还是显式的安装器,帮用户处理
只有这个比较简单、中规中矩。并且可靠,是被广泛测试过可靠的路径。
自己打包 Ruby 这条路,实际 Ruby 或者 Gem 的打包一直是动态的,需要长期跟踪,成本太高。不建议个人做。
homebrew 学习 Rails 实际上并不是很好。
以 我的环境为例 MacOS 13.6.6(Intel) 为例
1)brew install ruby 确实可以正确安装 ruby
他的位置在 /usr/local/opt/ruby/bin/
都添加到 path。Ruby 自己的组件:ruby、gem、irb 都工作正常
2)当你 gem install rails,正常安装成功,如果你什么都不做,你根本找不到 rails,rails 无从执行。
因为它的位置在 /usr/local/lib/ruby/gems/3.3.0/bin/
,你需要自己添加到 PATH。
这对新手并不友好。位置在 M1(ARM) 系列的位置可能还不同。这个 PATH 谁来告知?搜索引擎 maybe。。。
实际上,用户得非常留意安装信息里面,才能看到这句;或者说很熟悉 homebrew,再去用 brew info ruby
重新获取。
By default, binaries installed by gem will be placed into:
/usr/local/lib/ruby/gems/3.3.0/bin
而且这个丑陋的 PATH 还依赖固定版本。
用户还得 会点 vim,maybe shell,知道当前终端是什么,初始化文件在哪儿,还得用 source。 而这一切默认你已经会了。新人不会被告知。 :(
ASDF 帮助解决了 python、ruby、nodejs ……
同感。asdf 确实不错,只是对于开发还 ok。对于只想运行 ruby 的人来说,还是太繁琐。
我还在研究 portable ruby。理想情况:做出了比较完善的,也可以做到直接下载,添加到 path 就可以工作了。免去了本地编译的问题。
这是最近想把 ruby 带着走,产生的想法。
构建有一个过程,需要等待。编译完会自动安装 make install ....
结束就好了
emmm…… 是这样
1.Portable Ruby 可能更高级一点
比如你想把 Ruby+Rails+ 你的应用,带着走。用上面的可能合适。
但是没必要,因为你在学习 Rails 不要把自己放在这些奇怪的情境中。
2.如果你只想正常运行 ruby,开发 Rails,而且不想遇到 sudo 问题
我推荐 asdf,这也是我本人开发用的个 asdf 可以管理多个语言、数据库、任何版本相关的。
1)在这里 https://asdf-vm.com/ 安装 asdf
2)添加 ruby
https://github.com/asdf-vm/asdf-ruby
不过可能有点过时。在安装依赖这部分。Ruby 3.3.1 依赖 openssl@3 这是重点。
# 安装前置依赖
# ruby-build 是安装工具
# openssl@3 readline libyaml gmp 是必要的依赖
# rust 是 YJIT 必要的依赖,不装就不会构建 YJIT 功能
brew install ruby-build openssl@3 readline libyaml gmp rust
补一篇《使用 Ruby-build 在 MacOS 上 编译 Portable Ruby》https://ruby-china.org/topics/43710
随便试试,可以用 Ruby build 安装到任意路径,可移除。
# step1: 安装前置依赖
# ruby-build 是安装工具
# openssl@3 readline libyaml gmp 是必要的依赖
# rust 是 YJIT 必要的依赖
brew install ruby-build openssl@3 readline libyaml gmp rust
# step2: 编译安装
# $HOME/ruby 替换成你要安装的目录
# 搜索到 ruby 需要把 $HOME/ruby/bin 添加到到你的 PATH
ruby-build 3.3.1 $HOME/ruby
长期使用,推荐 asdf 安装,统一管理。ruby 插件的底层依然是 ruby-build
今天我在群里,提出了类似的问题。
Ruby 在 MacOS 上的安装,有点不友好。
不如 Python、Java 简单粗暴