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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Podfile 解析最佳实践

發布時間:2023/12/31 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Podfile 解析最佳实践 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

基本語法


首先需要做的是,看懂一個 Podfile。那么需要了解一些最基本的 ruby 語法,這部分非常簡單:

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

以上三行代碼是 Podfile 中最為常見的,其實這三行是在調用不同的方法。

方法調用

Ruby 中,方法調用的參數列表可以以空格形式接在方法名后,多個參數以逗號隔開,所以等價于:

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

如果是最后一個參數是字典,那么字典的大括號也可以省略,所以 pod 的調用等價于:

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

符號(Symbol)

Symbol 是 Ruby 中的一種對象類型,一般作為名稱標簽,為了不影響閱讀,我把 Symbol 的定義放在最后,這里可以暫且把它當做前面加了 : 的 string。

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

方法定義

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

方法名

比如 :nil?, empty?, merge! 這類方法。

方法名小寫,可包含 !? 這類符號。用法可以學習系統的定義:

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

所以,Podfile 中出現的 use_frameworks! 也是在調用方法。

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

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

常見的 pod 調用如上,通過調用就能猜出 pod 方法的聲明:

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

大致就是這樣,這里的 * 和指針沒關系 🌚。完整參數列表的定義方式,我寫在文末吧。

返回值
其實解析這部分用不上返回值,不過可以介紹一下。Ruby 返回值有以下幾個特點:

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

target :Meitu dopod 'Masonry' end

do…end 可以看成大括號,:Meitu 是 target 方法的第一個參數。綜合之前介紹的語法,target 的定義就呼之欲出了:

# tname: target 名稱 # block: 回調 def target(tname, &block)# ...# 調用yield if block_given? end

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

解析


既然 Podfile 中是 Ruby 代碼,也就表示,可以通過調用 Ruby 腳本的方式,直接執行 Podfile。

ruby ~/Desktop/Podfile

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

定義方法

首先需要定義解析需要調用的方法,讓指定的變量乖乖的被對應參數接收。最簡易的版本,需要實現 target 和 pod 兩個方法:

target

工程可能對應多個 target,具體要解析哪個 target,需要對應到打包時指定的 target,所以采用外部傳入的方式:$target_argv:

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

pod

實現 pod 以后,就可以通過參數讀取這種值了。同樣,pod 可能包含 configuration 信息,這也是需要對應打包的 configuration 參數的:

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

method_missing
除了 target 和 pod 方法外,Podfile 中還存在 source、platform 等各種各樣的方法,一一實現是不可能的。對此,Ruby 提供了 method_missing 方法,該方法的作用類似于消息轉發。當程序調用沒有實現的方法時,統一走 method_missing。

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

因為我們不需要處理未實現方法的邏輯,所以方法體是空的,不需要實現。

導出
到此,整個解析就已經完成了,比起以前用正則寫的版本,清爽了很多。最后一步,將解析結果導出為 JSON 文件。代碼很簡單:

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

Podfile.lock

這里簡單提一下 lock 文件,因為 lock 文件中有準確的版本號,所以對應引用版本都從 lock 當中讀取。而 lock 文件其實是 yaml 格式的,可以通過 yaml 庫將它解析為 hash 和 array 進行讀取。

整個流程

那么,應該如何將解析和導出兩個步驟串起來呢?方法需要定義在代碼開頭,導出需要放在代碼末尾,所以有了以下結構:

定義

eval(File.read(podfile_path))

導出

這里用到了非常強大的 eval 函數,也就是將 podfile 內容讀取為將字符串并當做代碼執行。

ruby inject_template.rb target_name configuration_name result_path podfile_path

🚣? 🚣 🚣? 🚣?

最后
Symbol
Symbol 是 Ruby 中最為基礎的對象類型,存儲在 Symbol Table 中,可以看做 name 和 ID 的對應。Symbol 不可寫,地址不變,全局唯一。這和 String 不同,兩個值相同的 String,其實是不同的地址。

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

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

如果想繼續了解 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,位置參數。也就是說,聲明在第一個,第一個傳入的就一定是 a 接收。
b:和 a 含義相同,且有默認值。
c:連續多個 Positional argument。
d:Keyword argument,對位置沒要求,接收指定 keyword 對應的值。
e:和 d 含義相同,且有默認值。
f:連續多個 Keyword argument。
g:block。

總結

以上是生活随笔為你收集整理的Podfile 解析最佳实践的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。