Ruby 设计 - 基础语法
一、脚本语言
我似乎对于 Python 和 Ruby 强求太多了,我要让他们实现 C 的所有功能。他们确实可以实现所有的功能,但是他们的目的不是为了这个。
我也可以用 shell 实现很多复杂的算法,但是我绝对不会用他去写图着色或者动态规划。但是我使用 python 和 Ruby 的时候却又这种倾向。我不会强求 C 为我列出目录中的所有文件,但是我却会强求 python,可叹啊。
我之前似乎把语言看成了算法和架构的载体和实现,怪不得过得这么不幸福。
二、调用命令
神奇用法,可以直接调用 ls 这样的指令。
print <<`EOC` # 执行命令 |
这或许进一步说明了它就是个脚本。
三、外部传参
ruby 的脚本调用的时候是可以传参的,下面的脚本
puts ARGV.class |
如果在 zsh 中输入
ruby argv.rb 1 2 3 |
那么输出是
Array |
就是将后面的输入视为一个数组,原理比较显然。
四、输入输出
输出比较简单的是 puts 类似于 C 语言中 puts(有种传言说 ruby 特意模仿了一些 C)。如果想要格式化输出,也是可以的,见下
# format output |
输入没有细致探讨过,似乎这个是可以的
# input |
五、文件操作
跟 C 依然很像,太像了
filename = ARGV.first |
六、数据结构
6.1 Hash
HashMap 的意思,感觉比 Java 的还好用,语法有点像 C++。
grades = {'CNX' => 100, 'QS' => 0, 'LSZ' => 120} |
6.2 语句块
这是一个很有意思的东西,就是我们可以定义一个被叫做 “块 “的结构,有两种写法
do |x| |
然后这个块结构就可以作为函数参数传参了(感觉有点函数式和匿名函数的意思了),比如说这个
grades.each do |name, grade| |
其实是作为 hash 的 grades 对象调用 each 方法,这个方法有一个参数,就是这个块
grades.each (do |name, grade| |
6.3 整数
取整的时候是向下取整,而不是向零取整,这点与 C 或者 Java 不同,但是与 Python 相同。
6.4 Array
声明形式是这样的
a = [1, 2, 3, 4] |
有的时候还可以骚一点
a = Array.new(4) {|i| i + 1} |
对于数组的索引访问,跟 python 一样强大,支持负数。
puts a[0] # 1 |
和 python 一样,支持切片
b = Array.new(5) {|i| (i + 'A'.ord).chr} |
同时有了一堆好用的操作符
c = [1, 2, 3] |
6.5 Range
似乎 python 中也有这种结构,但是这个似乎被当成了独立的一种内置的数据结构
(1..5) #==> 1, 2, 3, 4, 5 |
6.6 Symbol
符号,就是编译原理里符号表里的那个符号,Ruby 的神奇就在于可以直接在程序中定义这个符号,方法是加个标识符
a = :s |
七、注释
单行注释
# There is a single line comment |
多行注释
=begin |
八、标识符里的标点符号
$var # 全局变量 |
九、迭代器
这里的迭代器其实不是一个 Java 或者 cpp 中出现的跟指针一样可以自增的东西,而是一个方法,这个方法接受一个代码块作为参数。这里利用了关键词 yield 。示例如下,我模拟了一个数组,然后实现了它的迭代器方法 each
class MyArray |
可以看到,对于 each 方法,在实现中进行了遍历,但是并没有说明遍历要干什么,只是有一个
yield @a[i] |
对于这个情况, yield 会调用我们传给他的代码块,也就是
do |e| puts e end |
然后给形参 e 赋值 @a[i] ,然后对于数组中的每个元素有一个 puts e 的操作,相当于这个
for i in 0...@a.size |
可以看到代码块的这种方式,大大拓展了原有函数的功能。
我们可以再看一个例子,这个例子不是类中的例子,而就是普通的一个方法,用于输出一个等差数列。
def sequence(n, step, c) |