Chapter 1a: Ruby as a Computer Language

本文将Array, String, Hash统称为collections 因为他们都由很多个基本类型的元素组成。

1. Basics

1.1 取Array和String的一部分

str = "abcd"
str[1..-1]          # => 'bcd'

arr = [ele0, ele1, ele2, ele3]
arr[1..3]           # => [ele1, ele2, ele3]

1.2 Tenary 用于正反两种情况下的不同值

value = condition ? x : y   # value要么是 x 要么是 y

if ... else ... 也可以覆盖所有情况

if 或者 if elsif 则未必,因为他们只注明了某些情况

1.3 *args_arr *args_arr代表把传入的多个变量打包args_arr这个Array

1.4 Block和Proc

Block 指具体的一个操作 {|ele| ele * 2 }, Proc 是指把这个操作变成一个变量: Proc.new {|ele| ele * 2}. &prc是指把传入的block赋值给prc这个 Proc。注意一个函数只能take一个block,但可以take很多Proc, 因为Proc和其他type并无本质差别。

circle-exclamation

1.5 命名规范

用单数代表一个东西,用复数代表一个这种类型的array。比如words代表一个Array,里面每个是word (string); procs代表一个Array, 里面每个是Proc

1.6 用Range.each的情况

circle-check

2. Block

  1. block只是do...end中间,或者{...}里面的一段代码。就是a block of code, that's it.

  2. 就像函数一样,block也是有结果的,只不过函数的结果可以用return关键词来代表,也可以用最后一行的表达式的值来代表。而block的结果只能用最后一行的表达式来代表.比如 do “hello" end的结果是"hello"

  3. block可以take参数,使得参数不同,block的结果也不同,比如 do |ele| ele * 2 end的结果自然和传入的ele的值有关。注意,这个参数的scope限制在block内。

  4. block对应其他语言中的lambda

3. Enumerators / 循环

circle-exclamation

3.1 arr.each并不会对block的结果做什么处理,所以需要自己处理赋值等操作

3.2 其他的循环,会根据每一个元素通过block(就像是通过一个funnel)的结果来整合,比如变换 / 筛选 / 聚合

circle-info

如果block内的内容也需要循环,推荐总是把block里的部分用一个新的函数来替代,这样函数的返回值一定是最后输出的结果。尤其是 array.select 这样需要boolean结论的enumerator。 写法上一个简单的原则是,一个循环就对应一个新函数。

3.3 当我们只需要处理array的一部分,并且我们知道idx的范围时,更适合用idx的range来做each

4. Reference (函数内外的沟通)

4.1 函数计算完之后,最常见的与外面沟通的方式就是通过返回值 return

4.2 Ruby的函数传的总是copy / value

circle-exclamation

4.3 对Collection in-place(原地)修改,必须要通过 collection[i] =或者collection[i] +=或者<<来修改或者map!reverse!之类的现成函数。 (对于Hash则是hash[key])

4.4 在新建一个Array或者Hash时, 如果每个元素是collection (比如Array of Arrays), 那么必须要通过block来初始化。否则每个元素都是同一个reference,改一个就会改所有。

circle-info

Hash.new {[]} 解决了default value用同一个reference的问题,但并不会把这个default object放进hashhttps://stackoverflow.com/questions/2698460/strange-unexpected-behavior-disappearing-changing-values-when-using-hash-defaarrow-up-right

Last updated