Cache < Command 继承
https://www.cnblogs.com/tardis/p/4004438.html 更多继承
有时, 我们希望子类从父类继承来的方法可以做与父类不相同的事情,这就需要在子类中重写方法。例如, 你有一个类名字叫Email继承于类Message,两个类都有send方法,但是Email类的send方法需要有邮件地址和一系列邮件协议,但是Message中的send方法并不知道这些,与其在Email类中添加send_mail方法,而从父类继承的send方法弃之不用, 不如显式的修改send方法以适应Email的需求。
另一方面, 有时子类发现它所需要的继承自父类的方法已经被改写, 不要惊慌, 我们可以直接获取父类的响应方法, 这需要使用super关键字。
当你在方法中调用super, 这就是告诉Ruby,在父类中找到与调用super的这个方法同名的函数,如果找到, 那么Ruby将会使用其父类版本的这个方法。
:: 语法
@cache = Downloader::Cache.new(Config.instance.cache_root + 'Pods')
你可以通过在方法名称前加上类或模块名称和 . 来调用类或模块中的方法。你可以使用类或模块名称和两个冒号 :: 来引用类或模块中的常量。
:: 是一元运算符,允许在类或模块内定义常量、实例方法和类方法,可以从类或模块外的任何地方进行访问。
请记住:在 Ruby 中,类和方法也可以被当作常量。
多行字符串
https://www.runoob.com/ruby/ruby-syntax.html
#!/usr/bin/ruby -w
# -*- coding : utf-8 -*-
print <
<<-EOS
### Installation Source
```/
Executable Path: #{actual_path}
```/
EOS
返回值
https://www.runoob.com/ruby/ruby-method.html
Ruby 中的每个方法默认都会返回一个值。这个返回的值是最后一个语句的值
。例如:
def actual_path
$PROGRAM_NAME
end
Ruby语法解释:attr_reader,attr_writer和attr_accessor
解释
变量set 和get
attr_accessor :required
alias_method :required?, :required
# @return [Boolean]
# Indicates if the argument is repeatable (= can appear multiple
# times in the command, which is indicated by '...' in the banner)
#
attr_accessor :repeatable
attr_accessor :abc
等同于
def abc
return @abc
end
def abc=(abc)
@abc = abc
end
ruby中的alias和alias_method
new_name 和old_name
(12)alias :new_name :old_name 可以用来给方法取别名。alias是个关键字,和他类似的还有一个Module#alias_method方法
https://blog.csdn.net/raosheng1993/article/details/45458821 的第12点
if 语法
https://haicoder.net/ruby/ruby-else.html 这里面有所有的if语法记录
message = verbose_prefix + message if config.verbose?
puts_indented message if config.verbose?
如果 if 语句条件为真,则会执行相对应的代码
#!/usr/bin/ruby -w
# -*- coding : utf-8 -*-
puts "HaiCoder(www.haicoder.net)"
$debug=1
print "debug\n" if $debug
程序运行后,控制台输出如下:
因为 debug 变量为 1,所以我们这里输出了 debug。
Ruby if修饰符总结
在 Ruby 中,if 修饰词组表示当 if 右边之条件成立时才执行 if 左边的式子。即如果 conditional 为真,则执行 code。
:语法
冒号:
https://www.jianshu.com/p/28d7f3a17b29
# spec.authors = { "#{data[:author_name]}" => "#{data[:author_email]}" }
def pod(set, mode = :normal)
if mode == :name_and_version
puts_indented "#{set.name} #{set.versions.first.version}"
else
当我说{ :bla => 1, :bloop => 2 }时,:到底是做什么的?我在某个地方读到过关于它是如何类似于一个字符串,但不知怎的是一个符号.
:foo是一个名为"foo"的符号.符号有一个明显的特点,即任何两个命名相同的符号都是相同的:
"foo".equal? "foo" # false
:foo.equal? :foo # true
这使得比较两个符号的速度非常快(因为只涉及指针比较,而不是像比较字符串中的所有字符那样),而且不会有大量相同符号的副本.
此外,与字符串不同,符号是不可变的.
unless 用法
help! 'A Podfile path is required.' unless @path
https://haicoder.net/ruby/ruby-unless.html
在 Ruby 中,unless 语句和 if 语句作用相反,即如果 conditional 为假,则执行 code。如果 conditional 为真,则执行 else 子句中指定的 code。
Ruby unless语句详解
语法
unless conditional [then]
code
[else
code ]
end
include ProjectDirectory 用法
unless repl_command == '\n'
def execute_repl_command(repl_command)
unless repl_command == '\n'
repl_commands = repl_command.split
subcommand = repl_commands.shift.capitalize
arguments = repl_commands
subcommand_class = Pod::Command::IPC.const_get(subcommand)
subcommand_class.new(CLAide::ARGV.new(arguments)).run
signal_end_of_output
end
end
concat(super)
def self.options
[
['--template-url=URL', 'The URL of the git repo containing a compatible template'],
].concat(super)
end
private
用法
ensure 关键字
当一个方法结束工作时我们也许需要进行清理工作.也许一个打开的文件需要关闭,缓冲区的数据应清空等等.如果对于每一个方法这里永远只有一个退出点,我们可以心安理得地将我们的清理代码放在一个地方并知道它会被执行;但一个方法可能从多个地方返回,或者因为异常我们的清理代码被意外跳过.
使用 ensure 语句
有时候,无论是否抛出异常,您需要保证一些处理在代码块结束时完成。例如,您可能在进入时打开了一个文件,当您退出块时,您需要确保关闭文件。
ensure 子句做的就是这个。ensure 放在最后一个 rescue 子句后,并包含一个块终止时总是执行的代码块。它与块是否正常退出、是否抛出并处理异常、是否因一个未捕获的异常而终止,这些都没关系,ensure 块始终都会运行。
https://www.runoob.com/ruby/ruby-exceptions.html
yield if block_given?
from_path = config.podfile_path.dirname if config.podfile_path
if pathname
from_path = config.podfile_path.dirname if config.podfile_path
from_path ||= Pathname.pwd
path = begin
Pathname(pathname).relative_path_from(from_path)
rescue
pathname
end
"`#{path}`"
else
https://juejin.cn/post/6844903683524673550 讲了block的回调
private
https://blog.csdn.net/qq284489030/article/details/88369791
总结一下
public方法可以被定义它的类和子类访问,并可以被类和子类的实例对象调用;
protected方法可以被定义它的类和子类访问,不能被类和子类的实例对象调用,但可以被该类和子类的实例对象(所有)访问;
private方法可以被定义它的类和子类访问,不能被类和子类的实例对象调用,且实例对象只能访问自己的private方法。
问号
def repo_update?(default: false)
if @repo_update.nil?
default
else
@repo_update
end
end
def initialize(argv)
@repo_update = argv.flag?('repo-update')
super
end
在Ruby中有很多方法是以?和!号结尾的
“?”被用于标示谓词,即返回Boolean直的方法,如Array.empty?(判断数组中元素是否为空)
“!”出现在方法名尾部的感叹号表明使用该方法是需要多加小心。许多Ruby的核心类都定义了
成对的方法,它们具有同样的名称,只是结尾相差一个“!”,通常情况下,不带感叹号的方法返
调用该方法的一个拷贝,二带感叹号的方法则是一个可变方法,该方法会修改原来的对象,如Array
类中的sort和sort!
ruby中的方法可以以问号和叹号结尾,问号通常用于谓语方法,这种方法返回一个布尔值。例如array和hash类都定义了一个empty?方法,这个方法用于测试数据结构中有没有元素。
如果方法以叹号结尾,这意味着我们在使用这个方法的时候要小心,比如大多数核心的ruby类库方法都提供两个同名的方法,一个以叹号结尾,一个没有,
区别在于,如果使用没有叹号结尾的方法,你在调用它的时候会得到当前对象的一个拷贝而不会修改原始对象,而如果使用带有叹号的方法,你在调用它的时候会直接修改当前对象的值。
叹号 !
2.以感叹号结尾的方法。一般表示这是危险的,或者会修改接收者对象的方法。
def insert_sort!
(0...self.length).to_a.each do |j|
key = self[j]
i = j - 1;
while i >= 0 and self[i] > key
self[i+1] = self[i]
i = i-1
end
self[i+1] = key
end
self
end`
运行上述代码之后,会对传入的数据进行排序,修改了(接收者)对象。
Ruby核心类都定义了成对的方法,它们有同样的名字,彼此的差别在于其中一个以感叹号结尾,而另一个没有,通常情况下,不带感叹号的方法返回调用该方法的对象的一个修改过的拷贝,而带感叹号的方法则是一个可变的方法,该方法会修改原对象。
3.以等号结尾的方法。一般被赋值的方法以等号结尾。
def validate!
def validate!
<<
``` section << " (branch `#{@branch}`)" if @branch```
方法传参 (关键字参数)
7.3.4 关键字参数
https://www.kancloud.cn/imxieke/ruby-base/107294
关键字参数是 Ruby 2.0 中的新特性。
在目前为止介绍过的方法定义中,我们都需要定义调用方法时的参数个数以及调用顺序。而使用关键字参数,就可以将参数名与参数值成对地传给方法内部使用。
使用关键字参数定义方法的语法如下所示:
def 方法名(参数 1: 参数 1 的值, 参数 2: 参数 2 的值, …)
希望执行的处理
end
除了参数名外,使用“参数名 : 值”这样的形式还可以指定参数的默认值。用关键字参数改写计算立方体表面积的 area 方法的程序如下所示:
def area2(x: 0, y: 0, z: 0)
xy = x * y
yz = y * z
zx = z * x
(xy + yz + zx ) * 2
end
p area2(x: 2, y: 3, z: 4) #=> 52
p area2(z: 4, y: 3, x: 2) #=> 52 (改变参数的顺序)
p area2(x: 2, z: 3) #=> 12 (省略y)
这个方法有参数 x、y、z,各自的默认值都为 0。调用该方法时,可以像 x: 2 这样,指定一对实际的参数名和值。在用关键字参数定义的方法中,每个参数都指定了默认值,因此可以省略任何一个。而且,由于调用方法时也会把参数名传给方法,所以参数顺序可以自由地更改。
不过,如果把未定义的参数名传给方法,程序就会报错,如下所示:
area2(foo: 0) #=> 错误:unknown keyword: foo(ArgumentError)
为了避免调用方法时因指定了未定义的参数而报错,我们可以使用“** 变量名”的形式来 接收未定义的参数。下面这个例子的方法中,除了关键字参数 x、y、z 外,还定义了 **arg 参数。参数 arg 会把参数列表以外的关键字参数以散列对象的形式保存。
def meth(x: 0, y: 0, z: 0, **args)
[x, y, z, args]
end
p meth(z: 4, y: 3, x: 2) #=> [2, 3, 4, {}]
p meth(x: 2, z: 3, v: 4, w: 5) #=> [2, 0, 3, {:v=>4, :w=>5}]
关键字参数与普通参数的搭配使用
关键字参数可以与普通参数搭配使用。
def func(a, b: 1, c:2)
┊
end
上述这样定义时,a 为必须指定的普通参数,b、c 为关键字参数。调用该方法时,可以像下面这样,首先指定普通参数,然后是关键字参数。
func(1, b: 2, c: 3)
用散列传递参数
调用用关键字参数定义的方法时,可以使用以符号作为键的散列来传递参数。这样一来,程序就会检查散列的键与定义的参数名是否一致,并将与散列的键一致的参数名传递给方法。
def area2(x: 0, y: 0, z: 0)
xy = x * y
yz = y * z
zx = z * x
(xy + yz + zx ) * 2
end
args1 = {x: 2, y: 3, z: 4}
p area2(args1) #=> 52
args2 = {x: 2, z: 3} #=> 省略y
p area2(args2) #=> 12
方法调用
branch_name, = Executable.capture_command('git', %w(name-rev --name-only HEAD), :capture => :out, :chdir => source.repo)
方法定义
def self.capture_command(executable, command, capture: :merge, env: {}, **kwargs)
bin = which!(executable)
require 'open3'
command = command.map(&:to_s)
case capture
when :merge then Open3.capture2e(env, [bin, bin], *command, **kwargs)
when :both then Open3.capture3(env, [bin, bin], *command, **kwargs)
when :out then Open3.capture3(env, [bin, bin], *command, **kwargs).values_at(0, -1)
when :err then Open3.capture3(env, [bin, bin], *command, **kwargs).drop(1)
when :none then Open3.capture3(env, [bin, bin], *command, **kwargs).last
end
end
箭头 向左, 向右
Ruby语言的非操作符(Nonoperator)和操作符(Operator)
https://www.huoxiaoqiang.com/ruby/rubylang/1516.html
1.<< 和 >>代表左移或右移
puts 1<<2
输出结果为:4
代表1的二进制向左移动4位,即x<>
git!(%W(-C #{dir} pull))
https://www.delftstack.com/zh/howto/ruby/ruby-what-does-w-mean/
array = ["one", "two", "three"]
输出:
["one", "two", "three"]
它有效,但输入引号和逗号需要花费大量时间和精力。Ruby 为我们提供了更优雅的解决方案。
%w
语法用于创建字符串数组,而不需要在每个元素之间使用逗号或引号。
每个元素都将被视为一个字符串,并应以空格分隔。
array = %w[1 two 3.4 [] {}]
输出:
["1", "two", "3.4", "[]", "{}"]
if path =~ %r{https?://}
@podspecs_paths.each do |path|
if path =~ %r{https?://}
require 'cocoapods/open-uri'
output_path = podspecs_tmp_dir + File.basename(path)
=~
是正则表达式
https://www.runoob.com/ruby/ruby-regular-expressions.html
正则表达式是一种特殊序列的字符,它通过使用有专门语法的模式来匹配或查找字符串集合。
<<
files << (pathname = Pathname.new(path))
-
1.<< 和 >>代表左移或右移
puts 1<<2
输出结果为:4
代表1的二进制向左移动4位,即x<
2*y。平时用不到这种方法 -
2.字符串拼接
test = "you"
txt = "sb"
p test<
输出结果为:yousb
-
3.数组添加元素
ar = Array.new
ar<<3
p ar
输出结果为:[3]
**字符串拼接和数组添加元素不能使用>>
reject的用法
].concat(super).reject { |(name, _)| name == '--no-repo-update' }
reject和reject!
reject返回不满足代码块的元素数组
reject!删除数组中满足代码块的元素
a=[1,2,3,5]
a.reject! {|x| x<4}
p a #[5]
b = [1,2,3,4,5]
c = b.reject {|x| x>4}
p c
p b
[1, 2, 3, 4]
[1, 2, 3, 4, 5]
||= 的符号
@lockfile ||= begin
https://blog.csdn.net/lihuan974683978/article/details/8686297
a||=123
就是 当a存在但是没有赋值时 a=123
extend 关键字
extend:在定义类时使用,把module的实例方法作为当前类的类方法.
module Test
def class_type
"This class is of type:#{self.class}"
end
end
class TestClass
extend Test
end
puts TestClass.class_type #=> This class is of type:Class
module Pod
class Command
class Repo < Command
self.abstract_command = true
# @todo should not show a usage banner!
#
self.summary = 'Manage spec-repositories'
self.default_subcommand = 'list'
#-----------------------------------------------------------------------#
extend Executable
executable :git
def dir
config.repos_dir + @name
end
end
end
end
=> 箭头函数
=>将键与哈希映射文字中的值分开。它不可重载,也没有专门连接到符号。
哈希图文字的形式为{key1 => value1, key2 => value2, ...},但是当用作函数的最后一个参数时,可以省略花括号。因此,当您看到类似f(:a => 1, :b => 2)的函数调用时,将使用一个参数调用f,这是一个具有键:a和:b以及值1和2的哈希映射。
def pre_download(sandbox)
title = "Pre-downloading: `#{name}` #{description}"
UI.titled_section(title, :verbose_prefix => '-> ') do
target = sandbox.pod_dir(name)
begin
download_result = Downloader.download(download_request, target, :can_cache => can_cache)
rescue Pod::DSLError => e
raise Informative, "Failed to load '#{name}' podspec: #{e.message}"
rescue => e
raise Informative, "Failed to download '#{name}': #{e.message}"
end
spec = download_result.spec
raise Informative, "Unable to find a specification for '#{name}'." unless spec
def download_request
Downloader::Request.new(
:name => name,
:params => params,
)
end
? !
https://wenku.baidu.com/view/387eeb85f624ccbff121dd36a32d7375a417c6db.html
resuce
ruby 异常处理 begin rescue end
begin
代码1
rescue
代码2
end
如果执行 代码1 发生异常 则转至 代码2
若正常,则执行完跳出
运算符号
https://ke.qq.com/itdoc/ruby/ruby-operator.html
各种运算符
**
将右侧操作数指定为左侧操作数的指数
**=
指数幂并赋值运算符
<=>
组合比较运算符
.eql?
检查比较操作数相等和类型是否相同?
equal?
检查比较对象ID是否相等
//更多请阅读:https://www.yiibai.com/ruby/operators.html
<=>
组合比较运算符。如果第一个操作数等于秒,则返回0,如果第一个操作数大于第二个,则返回1,如果第一个操作数小于第二个则返回-1。
<=>
组合比较运算符。如果第一个操作数等于秒,则返回0,如果第一个操作数大于第二个,则返回1,如果第一个操作数小于第二个则返回-1。
10 等于?
如果接收方和参数具有相同的对象标识,则为真。
.join 和.tap 关键词
def self.capture_command!(executable, command, **kwargs)
capture_command(executable, command, **kwargs).tap do |result|
result = Array(result)
status = result.last
unless status.success?
output = result[0..-2].join
raise Informative, "#{executable} #{command.join(' ')}\n\n#{output}".strip
end
end
end
join方法的定义
>> a
=> [42, 8, 17, 7, "foo", "bar"]
>> a.join # 没有连接符
=> "428177foobar"
>> a.join(', ') # 连接符是一个逗号和空格
=> "42, 8, 17, 7, foo, bar"
https://ruby-china.org/topics/5348
分享 Rails 技巧之 tap & try
当读者遇到:
user = User.new
user.username = "foobar"
user.save!
他们必须遵循所有三行,然后才能认识到它只是在创建一个名为user.
如果是:
user = User.new.tap do |u|
u.username = "foobar"
u.save!
end
那么这将立即清楚。读者不必阅读块内的内容即可知道实例user已创建。
正如博主所做的那样,使用点击只是一种方便的方法。在您的示例中,这可能有点矫枉过正,但在您想与用户一起做很多事情的情况下,点击可以说提供了一个更简洁的界面。因此,也许在以下示例中可能会更好:
user = User.new.tap do |u|
u.build_profile
u.process_credit_card
u.ship_out_item
u.send_email_confirmation
u.blahblahyougetmypoint
end
使用上面的方法可以很容易地快速看到所有这些方法都组合在一起,因为它们都引用同一个对象(本例中的用户)。替代方案是:
user = User.new
user.build_profile
user.process_credit_card
user.ship_out_item
user.send_email_confirmation
user.blahblahyougetmypoint
同样,这是有争议的 - 但可以证明第二个版本看起来有点混乱,并且需要更多的人工解析才能看到所有方法都在同一个对象上被调用。
gsub
https://blog.csdn.net/sqlxx/article/details/8164554
ruby中带“!"和不带"!"的方法的最大的区别就是带”!"的会改变调用对象本身了。比方说str.gsub(/a/, 'b'),不会改变str本身,只会返回一个新的str。而str.gsub!(/a/, 'b')就会把str本身给改了。
但是gsub和gsub!还有另外一个不同点就是,gsub不管怎么样都会返回一个新的字符串,而gsub!只有在有字符被替换的情况下才会返回一个新的字符串,假如说没有任何字符被替换,gsub!只会返回nil.
example:
'abc'.gsub(/a/, 'b') #返回'bbc'
'abc'.gsub!(/a/, 'b') #返回'bbc'
'abc'.gsub(/d/,'a') #返回'abc'
'abc'.gsub!(/d/, 'a') #返回nil
scan match
https://blog.csdn.net/cz9025/article/details/90202839
用法:
新建文件xx.rb内容为:
module ModuleName
def fn
p "module cz"
end
end
以获得module名为例:
Dir["xx.rb"].each do |file|
name1 = File.read(file).scan(/module (.*)/)
p name1
name2 = File.read(file).match(/module (.*)/)
p name2
name3 = File.read(file).scan(/hh (.*)/)
p name3
name4 = File.read(file).match(/hh (.*)/)
p name4
end
运行结果为:
区别
scan:
查找全部匹配的内容,返回一个数组。
如果未匹配到,返回[]。
返回结果:()匹配到的内容。
match:
只匹配第一次,返回为MatchData类型。
如果未匹配到,返回nil。
返回结果:完整匹配部分+()匹配到的内容。
.map(&:to_s)
https://wenku.baidu.com/view/39aae24e26c52cc58bd63186bceb19e8b8f6ecae.html
Hash.key?(obj)方法
https://www.nhooo.com/note/qa55qj.html
在本文中,我们将研究Hash.key?(obj)方法。由于该方法的名称完全不同,因此无法进行假设。让我们阅读其定义并在语法和程序代码的帮助下了解其实现。
方法说明:
该方法是Public实例方法,属于Hash类,它位于Ruby语言库中。Hash.key?()方法用于检查键(键值)是否为特定Hash实例的一部分,并且该Hash实例应为普通的Hash实例。它将搜索整个哈希,并根据其搜索结果。让我们来看一下语法,并演示该方法的程序代码。
如果您正在考虑它将返回什么,那么让我告诉您,它将返回一个布尔值。如果在哈希表中找到键,则返回值将为true;如果找不到哈希表实例的一部分,则返回值为false。
语法:
Hash_instance.key?(obj)
Argument(s) 需要:
此方法仅使用一个参数,而该参数不过是我们要检查其存在性的键。
范例1:
=begin
Ruby program to demonstrate Hash.key? method
=end
hsh = {"colors" => "red","letters" => "a", "Fruit" => "Grapes"}
puts "Hash.key? implementation:"
puts "Enter the Key you want to search: "
ky = gets.chomp
if (hsh.key?(ky))
puts "Key found successfully"
else
puts "Key not found!"
end
输出
Hash.key? implementation:
Enter the Key you want to search:
colors
Key found successfully
在上面的代码中,您可以观察到我们在普通的Hash实例上调用Hash.key?()方法。当它在用户输入的哈希对象中发现键存在时,它返回true。
范例2:
=begin
Ruby program to demonstrate Hash.key? method
=end
hsh = {"colors" => "red","letters" => "a", "Fruit" => "Grapes"}
hsh1 = {"cars" => "800","bike" => "pulsar", "phone" => "A50"}
hsh2 = {"one"=> hsh, "two" => hsh1}
puts "Hash.key? implementation:"
puts "Enter the Key you want to search: "
ky = gets.chomp
if (hsh2.key?(ky))
puts "Key found successfully"
else
puts "Key not found!"
end
输出结果
Hash.key? implementation:
Enter the Key you want to search:
colors
Key not found!
说明:
在上面的代码中,您可以验证Hash.key?()方法不适用于作为多个Hash实例集合的Hash实例。即使对象是Hash实例的一部分,它也会返回false。