日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Podfile 解析最佳实践

發(fā)布時(shí)間:2023/12/31 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Podfile 解析最佳实践 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

基本語(yǔ)法


首先需要做的是,看懂一個(gè) Podfile。那么需要了解一些最基本的 ruby 語(yǔ)法,這部分非常簡(jiǎn)單:

source 'https://github.com/CocoaPods/Specs.git' platform :ios, '8.0' pod 'FLEX', :configurations => ['Debug'], :branch => 'develop' use_frameworks!

以上三行代碼是 Podfile 中最為常見(jiàn)的,其實(shí)這三行是在調(diào)用不同的方法。

方法調(diào)用

Ruby 中,方法調(diào)用的參數(shù)列表可以以空格形式接在方法名后,多個(gè)參數(shù)以逗號(hào)隔開(kāi),所以等價(jià)于:

source 'https://github.com/CocoaPods/Specs.git' # => source('https://github.com/CocoaPods/Specs.git')platform :ios, '8.0' # => platform(:ios, '8.0')

如果是最后一個(gè)參數(shù)是字典,那么字典的大括號(hào)也可以省略,所以 pod 的調(diào)用等價(jià)于:

pod 'FLEX', :configurations => ['Debug'], :branch => 'develop' #=> map = {:configurations => ['Debug'],:branch => 'develop' } pod('FLEX', map)

符號(hào)(Symbol)

Symbol 是 Ruby 中的一種對(duì)象類(lèi)型,一般作為名稱(chēng)標(biāo)簽,為了不影響閱讀,我把 Symbol 的定義放在最后,這里可以暫且把它當(dāng)做前面加了 : 的 string。

所以,上面的代碼中,出現(xiàn)的 :ios:configuration:branch 以及常見(jiàn)的 :git:tag 等都是 Symbol。

方法定義

Ruby 的方法定義更加靈活,語(yǔ)義也更加豐富。

方法名

比如 :nil?, empty?, merge! 這類(lèi)方法。

方法名小寫(xiě),可包含 !? 這類(lèi)符號(hào)。用法可以學(xué)習(xí)系統(tǒng)的定義:

? 常用于判斷,取代了 is_ 開(kāi)頭的定義習(xí)慣。
! 常用于需要注意的方法,比如 arr.merge!(other_arr) 表示合并到 arr;與之對(duì)應(yīng)的是 arr.merge(other_arr),表示合并,但不修改 arr,而是返回合并后的結(jié)果。
在很多開(kāi)源庫(kù)中,! 的用法就比較巧妙,有可能并不表示在當(dāng)前對(duì)象上進(jìn)行修改,僅僅為了優(yōu)雅好看也是可能的。

所以,Podfile 中出現(xiàn)的 use_frameworks! 也是在調(diào)用方法。

參數(shù)列表
為了簡(jiǎn)單,這里僅介紹可空的參數(shù)定義。還是以 pod 方法舉栗子:

pod 'Masonry' pod 'pop', '~> 1.0.7' pod 'Reachability', :git => 'xxx.git', :tag => 'v3.2.1'

常見(jiàn)的 pod 調(diào)用如上,通過(guò)調(diào)用就能猜出 pod 方法的聲明:

# pname: 庫(kù)名 # version: 指定版本,且可空 # map: 用鍵值對(duì)接收其他參數(shù) def pod(pod_name, version = nil, **map)# ... end

大致就是這樣,這里的 * 和指針沒(méi)關(guān)系 🌚。完整參數(shù)列表的定義方式,我寫(xiě)在文末吧。

返回值
其實(shí)解析這部分用不上返回值,不過(guò)可以介紹一下。Ruby 返回值有以下幾個(gè)特點(diǎn):

如果是最后一行,可以不寫(xiě) return。
支持多個(gè)返回值。
代碼塊(Block)
這個(gè)和 Objective-C 差不多,常用于回調(diào)。當(dāng)然 Podfile 也不缺少:

target :Meitu dopod 'Masonry' end

do…end 可以看成大括號(hào),:Meitu 是 target 方法的第一個(gè)參數(shù)。綜合之前介紹的語(yǔ)法,target 的定義就呼之欲出了:

# tname: target 名稱(chēng) # block: 回調(diào) def target(tname, &block)# ...# 調(diào)用yield if block_given? end

語(yǔ)法到這里就基本夠用了,接著介紹如何解析。

解析


既然 Podfile 中是 Ruby 代碼,也就表示,可以通過(guò)調(diào)用 Ruby 腳本的方式,直接執(zhí)行 Podfile。

ruby ~/Desktop/Podfile

然后就報(bào)錯(cuò)了…(編譯器又不知道 source,pod 這都是些什么方法…

定義方法

首先需要定義解析需要調(diào)用的方法,讓指定的變量乖乖的被對(duì)應(yīng)參數(shù)接收。最簡(jiǎn)易的版本,需要實(shí)現(xiàn) target 和 pod 兩個(gè)方法:

target

工程可能對(duì)應(yīng)多個(gè) target,具體要解析哪個(gè) target,需要對(duì)應(yīng)到打包時(shí)指定的 target,所以采用外部傳入的方式:$target_argv:

def target(target_name = nil, &block = nil)# target name 可能是 String,可能是 Symbol,統(tǒng)一 to_s 一下# 如果不是當(dāng)前打包的 target,直接返回就行了return if target_name.to_s != $target_argv# 調(diào)用 blockyield if block_given? end

pod

實(shí)現(xiàn) pod 以后,就可以通過(guò)參數(shù)讀取這種值了。同樣,pod 可能包含 configuration 信息,這也是需要對(duì)應(yīng)打包的 configuration 參數(shù)的:

def pod(pod_name, version = nil, **args)git = args[:git]branch = args[:branch]tag = args[:tag]commit = args[:commit]configurations = args[:configurations]# 如果 pod 指定了 configuration,則判斷是否包含當(dāng)前 configurationunless configurations.nil?return unless configurations.include?($configuration)end# 通過(guò)哪種方式引用,這里可以通過(guò) tag、commit、branch 的 nil? 來(lái)判斷來(lái)源comes_from = "tag"# $map 為全局變量$map[pod_name] = {comes_from: comes_from,version: version} end

method_missing
除了 target 和 pod 方法外,Podfile 中還存在 source、platform 等各種各樣的方法,一一實(shí)現(xiàn)是不可能的。對(duì)此,Ruby 提供了 method_missing 方法,該方法的作用類(lèi)似于消息轉(zhuǎn)發(fā)。當(dāng)程序調(diào)用沒(méi)有實(shí)現(xiàn)的方法時(shí),統(tǒng)一走 method_missing。

# m: 方法名 # args: 位置參數(shù)(也就是數(shù)組) def method_missing(m, *args); end

因?yàn)槲覀儾恍枰幚砦磳?shí)現(xiàn)方法的邏輯,所以方法體是空的,不需要實(shí)現(xiàn)。

導(dǎo)出
到此,整個(gè)解析就已經(jīng)完成了,比起以前用正則寫(xiě)的版本,清爽了很多。最后一步,將解析結(jié)果導(dǎo)出為 JSON 文件。代碼很簡(jiǎn)單:

File.open($result_path, "w") do |f|f.write(JSON.pretty_generate($map)) end

Podfile.lock

這里簡(jiǎn)單提一下 lock 文件,因?yàn)?lock 文件中有準(zhǔn)確的版本號(hào),所以對(duì)應(yīng)引用版本都從 lock 當(dāng)中讀取。而 lock 文件其實(shí)是 yaml 格式的,可以通過(guò) yaml 庫(kù)將它解析為 hash 和 array 進(jìn)行讀取。

整個(gè)流程

那么,應(yīng)該如何將解析和導(dǎo)出兩個(gè)步驟串起來(lái)呢?方法需要定義在代碼開(kāi)頭,導(dǎo)出需要放在代碼末尾,所以有了以下結(jié)構(gòu):

定義

eval(File.read(podfile_path))

導(dǎo)出

這里用到了非常強(qiáng)大的 eval 函數(shù),也就是將 podfile 內(nèi)容讀取為將字符串并當(dāng)做代碼執(zhí)行。

ruby inject_template.rb target_name configuration_name result_path podfile_path

🚣? 🚣 🚣? 🚣?

最后
Symbol
Symbol 是 Ruby 中最為基礎(chǔ)的對(duì)象類(lèi)型,存儲(chǔ)在 Symbol Table 中,可以看做 name 和 ID 的對(duì)應(yīng)。Symbol 不可寫(xiě),地址不變,全局唯一。這和 String 不同,兩個(gè)值相同的 String,其實(shí)是不同的地址。

"some_string".object_id == "some_string".object_id #=> false :some_string.object_id == :some_string.object_id #=> true

類(lèi)似于 Java 的 String 和 static String,一個(gè)是用完重新分配,一個(gè)是始終是一個(gè)存儲(chǔ)單元。針對(duì)于這個(gè)特性,Symbol 的效率會(huì)比 String 高一些。常用于成員變量名,hash 的 key 等。

如果想繼續(xù)了解 Symbol,推薦閱讀:

Understanding Differences Between Symbols & Strings in Ruby
Ruby Symbols
官方文檔
方法定義

def foo(a, b="b_default", *c, d:, e: "e_default", **f, &g)# do stuff end

a:Positional argument,位置參數(shù)。也就是說(shuō),聲明在第一個(gè),第一個(gè)傳入的就一定是 a 接收。
b:和 a 含義相同,且有默認(rèn)值。
c:連續(xù)多個(gè) Positional argument。
d:Keyword argument,對(duì)位置沒(méi)要求,接收指定 keyword 對(duì)應(yīng)的值。
e:和 d 含義相同,且有默認(rèn)值。
f:連續(xù)多個(gè) Keyword argument。
g:block。

總結(jié)

以上是生活随笔為你收集整理的Podfile 解析最佳实践的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。