经过粗略的看 Ruby 相关资源,看到了很多相似或相异却熟悉的点滴,还谈不上深刻体验,只能算记录。仍需用心探索,决定高层建筑需要夯实基础,理解原理,体会设计。

前言

分享两个有趣的链接

  • TryRuby:顾名思义,试试先。
  • Ruby.new:好看的皮囊千篇一律,有趣的灵魂万里挑一。

迭代器

先不厌其烦的记录下基础知识,闲话少叙。谈及迭代器(iteration),少不了谈到相似结构——循环(looping)。循环简要的说,是重复执行一段程序直到一个明确条件。迭代器是操作一个集合对象,如 Array 等,让集合每一个元素执行。 看看执行一个简单的迭代器

7.times do
  puts "Hello Iteration."
end
复制代码

输入指定条件,才会停止的循环

input = ""
while input != "quit"
  puts "ha,#{input}"
  input = gets.chomp
end
复制代码

一个使用 #each 迭代器的例子

colors = ["Yellow", "Red", "Black"]
colors.each do |color| #block 开始
  puts "#{color}" #block体
end #block 结束
复制代码

输出如下

?> colors = ["Yellow", "Red", "Black"]
=> ["Yellow", "Red", "Black"]
>> colors.each do |color|
?>   puts "#{color}"
>> end
Yellow
Red
Black
=> ["Yellow", "Red", "Black"]
复制代码

说到 iterator ,肯定和 block 强相关, 让我们走进 block 看看一些概念。

什么是块(block)? 一块在括号{}内部代码叫块(block),或者do / end 之间的代码块,块(block)使 ruby 更加特殊、强大、受欢迎。

什么是 | |? 被称为管道,调用迭代器 #each 时,管道内的变量充当传递给块的参数,传递到块中的每个元素将等于管道内的变量名称。为集合中的每个元素调用或运行块中的代码一次。#each方法每次取集合中的一个元素,并将其传递至块中,每个元素赋值给管道中的变量。

{ } 语法

colors = ["Yellow", "Red", "Black"]
colors.each {|color| puts "#{color}" }
复制代码

一切表达方法皆有值

任何表达式都有返回值,即使是nil,如下代码也有(有没有觉得不可思议)

x = 10
y = 11
z = if x < y
      true
    else
      false
    end
z # => true
复制代码

符号不是轻量的字符串

符号最好的描述是身份证。

>> :grackanil.object_id
=> 1145628
>> :grackanil.object_id
=> 1145628

?> "grackanil".object_id
=> 70162817382840
>> "grackanil".object_id
=> 70162817360420
复制代码

以上代码说明什么?说明当符号在使用过一次后,任何相同字符的符号都会在内存中指向同一个对象地址,也即是 object_id 相同。字符串就不同,每次都会分配新的空间,即 object_id 不同。

一切皆是对象

丝毫不夸张,整型都是对象。

?> 1.class
=> Fixnum
复制代码

可以改变的常量

只会有警告,但不会终止执行,但还是不建议修改。

命名约定

只是约定。

  • 局部变量以英文字母或者 _ 开头。
  • 全局变量以 $ 开头。
  • 实例变量以 @ 开头。
  • 类变量以 @@ 开头

关键值参数

从 Ruby 2.0 开始就有

def deliver(from: "A", to: nil, via: "mail")
  "Sending from #{from} to #{to} via #{via}."
end

deliver(to: "B")
# => "Sending from A to B via mail."
deliver(via: "Pony Express", from: "B", to: "A")
# => "Sending from B to A via Pony Express."
复制代码

真值

Ruby 把任何不是 nil 和 false 的值当作真值。和其他语言不同,可以说差异很大,其他语言,如 Python、C 等,都是会认为 0 和一些其他的值, 比如空的列表,会被当作假值。

# Ruby 中
if 0
  puts "0 为真"
else
  puts "0 为假"
end
# puts "0 为真"
复制代码

权限控制声明

权限声明会一直应用到类声明底部或者直到另外一个权限声明开始起作用。

  • public 是公开的。
  • private 表示只有非明确指定接收者允许调用。私有方法调用只允许 self 为接收者。
  • protected 可以被类及子类的实例调用,同一个类的其他实例也可以调用。 另外,publicprivateprotected 都是方法,可以传参,如果传递一个符号作为参数,那符号所代表的函数就是指定的权限。
?> method(:public)
=> #<Method: main.public>
复制代码

类是开放的

可以打开任何类,对它增加和修改。

Class Fixnum
  def month
    self * 30
  end
end
复制代码

1.month

以 ?和 !结尾的方法

首先,允许 ?和 ! 结尾。以问号结尾的方法表示返回布尔值,以感叹号结尾表示潜在“危险”方法,会修改self或参数。

Missing 方法

会将不存在的方法名,作为参数传递给 method_missingmethod_missing 默认会抛出一个 NameError 异常。根据需要可以,可以覆盖该方法。

def method_missing(id, *arguments)
  puts "调用了不存在的方法:#{id}。它的参数:#{arguments.join(", ")}"
end
1.sssss :a 2222
# 调用了不存在的方法:sssss。它的参数:a, 2222
复制代码

操作符是语法糖

大部分操作符仅仅是方法调用的语法糖,你可以覆盖。

=> #<Method: main.public>
>> class Fixnum
>>   def +(other)
>>     self - other
>>   end
>> end
=> :+
>>
?> 1 + 1
=> 0
复制代码

当然,也有一些操作符。

=, .., ..., not, &&, and, ||, or, ::, +=, *=
复制代码

消息传递

方法调用实际是消息传递,不是函数调用。将一条消息传递给另一个对象。