Ruby 学习(一)

前因

为什么要学习Ruby?我们都知道iOS 强大的包管理工具Cocoapods,Cocoapods正是使用Ruby进行编写,那么想要了解Cocoapods内部的实现原理,以及他架构方式,想必我们必须要学习他所使用的语言---即ruby。

初识

Ruby 背景

Ruby 这门语言呢是由日本人松本行弘 在20世纪90年代设计并开发的一种语言。那么Ruby呢,其实是一中完全面向对象的语言,在Ruby 里也是万物皆对象。当然Ruby 和 Python、JavaScript等脚本语言一样,它是一种需要解释的语言(也就是说它不需要进行编译、链接形成可执行二进制文件,而是需要一个解释器去解释执行)。据说火起来其实在2000年以后了(这个我就不知道了....)

Ruby 安装

MacOS 会内置Ruby, 默认Ruby一般版本较低,且不好升级

一般情况下,我们Linux 、MacOs 会采用三种方式安装Ruby:

  • 采用homebrew安装Ruby,brew install ruby, 配置环境变量 ``` echo 'export PATH="/usr/local/opt/ruby/bin:$PATH"' >> ~/.zshrc, 但是这是属于自管理ruby版本的方式,不推荐使用

  • 采用 RVM安装, RVM也就是Ruby Version Manager的首字母。可想而知他就是Ruby 版本管理器。

    • 首先需要安装RVM: curl -sSL https://get.rvm.io | bash -s stable --auto-dotfiles ,--auto-dotfiles 其实就是在安装rvm的时候,他会主动将环境变量配置好,不用我们自己在打开.bashrc/.zshrc 配置了。

    • 重启终端 | source ~/.zshrc, 输入命令 rvm --verison, 输出正常版本号则安装rvm成功

    • rvm list known 列出已知的所有Ruby版本

    • rvm install 3.1.2 安装制定ruby 版本

      • 可能会出现一个以下错误 :

        Error running '__rvm_make -j12',
        please read /Users/haoyh02/.rvm/log/1704359555_ruby-3.1.2/make.log
        There has been an error while running make. Halting the installation.

        通过查看make.log,我们发现报错是发生在openssl@3,大概原因应该就是安装Ruby的时候需要编译用到openssl, 当我们没有指定openssl路径的情况下,它就会默认到/usr/local/Cellar/ 下的openssl使用,但是正常我们使用brew 更新或者安装过openssl的话路径并不在这里,应该在/usr/local/opt/openssl@3 这里。这也就是导致编译的时候openssl的某些方法找不到等等错误

      • 解决版本则是:使用命令 rvm install 3.1.2 --with-openssl-dir=brew --prefix openssl| rvm install 3.1.2 --with-openssl-dir='/usr/local/opt/openssl@3'

        :) 这个问题也是让我很长时间找不到问题的原因。

    • 安装Ruby成功后, 使用rvm use 3.1.2 --default, 我们也可以使用rvm use 其他版本切换ruby 版本

    • ruby --verison 查看版本是否是我们安装的版本

  • 采用rbenv 安装,rbenv 是Ruby environment 的缩写,也就是Ruby 环境,同样也是一个Ruby 版本管理器。

    • 安装rbenv : brew install rbenv ruby-build, 当然也可以采用非home brew 手动安装:https://ruby-china.org/wiki/rbenv-guide, 手动安装就不赘述了,麻烦一些。

    • 安装完成后, rbenv install --list 列出可安装的Ruby 版本

    • rbenv install 3.1.2 安装制定ruby 版本

    • rbenv global 3.1.2 全局使用3.1.2的ruby, 类似于rvm use

那不禁就想问:那这三种方式的区别是什么,我们应该用哪一种?

那么对于homebrew 的方式(也就是第一种方式),只能安装一个版本的ruby,如果你多ruby开发,那么这种方式不合适了,因为它并不是ruby 版本管理工具,对吧?

其他两种来说,我也查阅了一些资料,总体来说rvm出来的更早,功能更全,但是rbenv也很好。换言之就是用谁都行,只要你觉得好就好~

所以推荐来说的话,还是使用rvm或者rbenv进行ruby安装以及版本管理~

对于Windows的安装请查阅文档:https://rubyinstaller.cn/ (因为我是Mac, 没有Windows,没有尝试,所以没有发言权😭)

ok,现在来说我们已经拥有基本的开发ruby的条件。

相关概念

对于我刚开始学习的时候,这几个概念也是对我造成了一定的困扰,并且我们要知道以下几个东西会一直陪在我们开发过程中的。所以对于他们的了解,可想而知多重要~

IRb

可交互式Ruby shell, 什么意思呢?就是我们可以直接在终端进行用IRb 命令解释Ruby 代码,举个栗子:

% IRb 
A gemspec development dependency (bacon, ~> 1.1) is being overridden by a Gemfile dependency (bacon, >= 0).
This behaviour may change in the future. Please remove either of them, or make sure they both have the same requirement
3.2.1 :001 > puts "hello world"
hello world
 => nil 
3.2.1 :002 >

如上,我们在命令行输入IRb后回车,就会进入到可交互shell 编程,我们可以去编写ruby,然后单行解释。

Gem

Gem 相当于是用Ruby 写的三方Gem 库的管理,通过Gem 我们可以安装所有现有的三方gem库。其实三方gem 包管理器。通过gem 可以进行安装gem 包。我们可以通过gem list --local 查看本地安装了的gem 包。其实我们回想一下cocoapods的安装,gem install cocoapods 对吧?所以其实我们的cocoapods他就是一个gem 包。

Bundler

说到bundler 那就不得不提,另外的两个工程里的文件:

Gemfile
Gemfile.lock

看着这两个是否有点感觉好熟悉的样子?想一想我们iOS工程采用Cocoapods管理的时候是否有类似的文件?

是的,我们iOS 工程如果采用Cocoapods管理的话,我们会有Podfile和Podfile.lock。 如果你对这两个文件了解的话,那其实Gemfile Gemfile.lock 也是同样的功能,因为Cocoapods的设计就是从Gem的设计借鉴而来的。

好了,我们还是解释一下这两个文件的作用吧

Gemfile: 同样是用来描述当前包依赖的三方gem包的,如下:

SKIP_UNRELEASED_VERSIONS = false
def cp_gem(name, repo_name, branch = 'master', path: false)
 return gem name if SKIP_UNRELEASED_VERSIONS
 opts = if path
 { :path => "../#{repo_name}" }
 else
 url = "https://github.com/CocoaPods/#{repo_name}.git"
 { :git => url, :branch => branch }
 end
 gem name, opts
end

source 'https://rubygems.org'

gemspec

group :development do
 cp_gem 'claide',                'CLAide'
 cp_gem 'cocoapods-core',        'Core'
 cp_gem 'cocoapods-deintegrate', 'cocoapods-deintegrate'
 cp_gem 'cocoapods-downloader',  'cocoapods-downloader'
end

Gemfile.lock: 如同它的类型名一样,他是用来锁定的,锁定什么?锁定你所依赖的三方gem包的版本的。同样和Podfile.lock一样防止多人开发协作,版本不一致的问题。

OK,那么我们来说一说它与Bundler的关系:

其实Bundler 和 我们Pod 命令很相似,在当前根目录下执行bundler install, 它会进行依赖解析、安装依赖。这是不是就和我们pod install 一样呢?

那么这么看呢?bundler 其实用来工程依赖解析、安装装的,其实具体的安装是通过gem安装的。

这样他们之间的关系是不是更加清晰了~

Rake

当我第一眼看到这个单词,我就想到了Make,但事实上他并不是一个单词,它是一个组合:Ruby Make。

我们在工程里可以看到有一个文件叫Rakefile。那么其实他们是相关联的。

刚才我们提到了Make,这个可不是仅仅是一个词啊,我想到的是C语言的构建工具Make, 同样他也有对应的文件makefile。

也就是说我们可以在Rakefile 定义一些列的任务,相当于任务脚本,执行rake 命令就可以执行任务。

比如CocoaPods工程下的Rakefile为:

# Bootstrap task
#-----------------------------------------------------------------------------#

desc 'Initializes your working copy to run the specs'
task :bootstrap, :use_bundle_dir? do |_, args|
 title 'Environment bootstrap'

 puts 'Updating submodules'
 execute_command 'git submodule update --init --recursive'

 if system('which bundle')
 puts 'Installing gems'
 if args[:use_bundle_dir?]
 execute_command 'env bundle install --path ./travis_bundle_dir'
 else
 execute_command 'env bundle install'
 end
 else
 $stderr.puts "\033[0;31m" \
 "[!] Please install the bundler gem manually:\n" \
 '    $ [sudo] gem install bundler' \
 "\e[0m"
 exit 1
 end
end
....

开发环境

开发环境可以说是我搞的时间最长的一个东西了。你知道如果你用VSCode 打开一个Gem项目,它的所有依赖、类的快速跳转、解释都没有、甚至提示都没有这对于开发来说多痛苦,更对于我想要阅读Cocoapods源码来说多痛苦,更是让我想到了?怎么开发gem 如果我有依赖三方gem。

首先我选择是VSCode Ide,作为开发IDE。其次经过研究,需要安装两个插件Ruby LSP、 Ruby Solargraph。安装了这两个插件按理来说就能实现方法、类跳转、解释。但是实际远比我想的复杂。当我安装了这两个插件之后,用VS code 打开工程,一直报错,错误则是LSP 无法连接服务、Solargraph启动失败等等,对应的VSCode 就不会有任何的解释、提示、跳转。

解决问题的过程总是复杂的、艰难的。最后发现我们需要进行以下几个步骤:

  1. 需要gem install solargraph

  2. 修改插件的设置,将LSP 的 ruby 管理工具改为你使用的,我则是rvm

  3. 增加setting.json 设置

   {
     "solargraph.commandPath": "/Users/haoyh02/.rvm/rubies/ruby-3.2.1/bin/",
     "rubyLsp.rubyVersionManager": "rvm",
     "solargraph.useBundler": true,
     "solargraph.references": true,
     "solargraph.autoformat": true,
     "solargraph.formatting": true
    }
  1. 在Gemfile中引用 LSP, Solargraph
    gem 'ruby-lsp'
    gem 'solargraph'
  1. 删掉Gemfile.lock, bundler install

  2. 重新打开vsCode, 打开工程即可

总结

兜兜转转,一直在学习的路上,但是新手么,难免会踩坑,当然踩坑也没有更好的方式解决,只能自己查资料、尝试解决。但是解决了就会收获成就感哦。

希望以上的经验可以帮助正在需要了解Ruby, 或者和我一样想要了解Cocoapods底层的朋友一些帮助。

相关文档

Ruby-China

一文搞清rake、Rakefile、gem、gemspec、bundler、bundle、Gemfile的关系

Rakefile

Ruby 教程

rvm 官网

rake github

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345

推荐阅读更多精彩内容