Skip to content

Head First Ruby

入门语法

ruby test.rb

交互执行

irb
irb --simple-prompt

‘’和”“

类似bash,单引号里变量不被解释

编码

# encoding: UTF-8

在Ruby 2.0中如果希望代码采用UTF-8的编码方式时,可省略魔法注释。

ruby -E UTF-8 脚本文件名
irb -E UTF-8

puts方法与print方法稍有区别,puts方法在输出结果的末尾一定会输出换行符

## 直接输出
print "Hello, Ruby.\n"
## 分隔同行输出
print "Hello, ", "Ruby", ".", "\n"
## 分隔换行输出
puts "Hello, ", "Ruby!"
## 使用p方法时,数值结果和字符串结果会以不同的形式输出
p "100"
p 100

变量与计算

Math.sin(3.1415)
Math.sqrt(10000)
x = 10
y = 20
z = 30
area = (x*y + y*z + z*x) * 2
volume = x * y * z
## 可以在字符串中使用 #{ 变量名 }这样
print " Area = #{area}\n"
print " Area = #{(x*y + y*z +z*x) * 2}\n"

注释

# 用 # 表示该行注释

=begin




=end

控制语句

a = 20
if a >= 10 then
    print "greater\n"
else
    print "smaller\n"
end

循环

i = 1
while i <= 10
    print i, "\n"
    i = i + 1
end
## times 方法被称为iterator

100.times do
  print "try iterator\n"
end

对象

数组

数组、散列这样保存对象的对象,我们称为容器(container)。

names = [" AA ", " B ", " CCC ", " D "]
names[0]
num = [3, 1, 4, 1, 5, 9, 2, 6, 5]
## 数组大小
num.size

## each遍历
names.each do |n|
    puts n
end

hash

在Ruby中,符号(symbol)与字符串对象很相似,符号也是对象,一般作为名称标签使用,表示方法等的对象的名称。

sym = :foo
sym2 = :"foo"

## 符号与字符串可以互相转换
>> sym = :foo
=> :foo
>> sym = :foo
=> :foo
>> sym.to_s
=> "foo"
>> "foo".to_sym
=> :foo

## 字符串与数字转换
ARGV[0].to_i
"5".to_i

散列创建

song = { :title => "Paranoid Android", :artist => "Radiohead"}
mark = { 11 => "Jack", 12 => "Queen", 13 => "King"}
person1 = { :name => " HT", :pinyin => "houteng"}
person2 = { name: " HT", pinyin: "houteng"}

散列使用

address = {name: " GQ", pinyin: "gaoqiao"}
address[:name]
address[:pinyin]
address[:tel] = "000-1234-5678"
address

散列循环

address.each do |key, value|
    puts "#{key}: #{value}"
end

正则表达式

模式与匹配

当模式中只使用英文、数字、汉字时,若希望匹配的字符串中包含模式中的字符串,则视为匹配成功,不包含则视为匹配失败。若匹配成功则返回匹配部分的位置。字符的位置和数组的索引一样,是从0开始计数的。也就是说,字符串的首个字符位置为0。反之,若匹配失败,则返回nil。

## /模式/ =~ 希望匹配的字符串

/Ruby/ =~ "Yet Another Ruby Hacker,"
/Ruby/ =~ "Ruby"
/Ruby/ =~ "Diamond"

## 正则表达式右边的/后面加上i表示不区分大小写匹配。
/Ruby/ =~ "ruby"
/Ruby/i =~ "ruby"
/Ruby/i =~ "rUbY"

命令行与文件

命令行的输入数据

print_argv.rb

puts " 首个参数: #{ARGV[0]}"
puts " 第2个参数: #{ARGV[1]}"
puts " 第3个参数: #{ARGV[2]}"
puts " 第4个参数: #{ARGV[3]}"
puts " 第5个参数: #{ARGV[4]}"
ruby print_argv.rb 1st 2nd 3rd 4th 5th

从文件中读取内容

read_text.rb

filename = ARGV[0]
file = File.open(filename)
text = file.read
print text
file.close
ruby read_text.rb FILE

read_text_simple.rb

filename = ARGV[0]
text = File.read(filename)
print text

read_text_oneline.rb

print File.read(ARGV[0])

逐行读取

read_line.rb

filename = ARGV[0]
file = File.open(filename)
file.each_line do |line|
    print line
end
file.close

提取目标行

simple_grep.rb

pattern = Regexp.new(ARGV[0])
filename = ARGV[1]
file = File.open(filename)
file.each_line do |line|
    if pattern =~ line
        print line
    end
end
file.close
ruby simple_grep.rb 模式 文件名

方法

hello_ruby2.rb

def hello
    puts "Hello, Ruby."
end
hello()
ruby hello_ruby2.rb

引用其它库、包

require "date"
days = Date.today - Date.new(1993, 2, 24)
puts(days.to_i)

Ruby除了提供p方法外,还提供了一个有类似作用的方法——pp。pp是英语prettyprint的缩写。要使用pp方法,我们需要使用require方法引用pp库。

require "pp"
books = [  
    { title: " AA", author: "BBB" }, 
    { title: "BBB", author: " HAHU" },  
    { title: "CCCCC", author: "Paul Gallico" },
]

p books
pp books

变量 常量 保留字

变量

  • 局部变量(local variable): 以英文小写字母或者 _ 开头。
  • 全局变量(global variable): 以$开头。
  • 实例变量(instance variable): 以@开头。
  • 类变量(class variable): 以@@开头。
  • 伪变量(pseudo variable): nil, true, false, self等。

常量

常量以大写英文字母开头。例如,Ruby的运行版本(RUBY_VERSION)、运行平台(RUBY_PLATFORM)、命令行参数数组(ARGV)等,都是Ruby预定义好的常量。

保留字

\_\_LINE\_\_
\_\_ENCODING\_\_
\_\_FILE\_\_
BEGIN
END
alias
and
begin
break
case
class
def
defined?
do
else
elsif
end
ensure
false
for
if
in
module
next
nil
not
or
redo
rescue
retry
return
self
super
then
true
undef
unless
until
when
while
yield

多重赋值

a, b, c = 1, 2, 3
## 变量前加上*,表示Ruby会将未分配的值封装为数组赋值给该变量。
a, b, *c = 1, 2, 3, 4, 5
## 交换变量
a, b = b, a
ary = [1, 2]
a, b = ary

类 class

类定义

class HelloWorld
  def initialize(myname = "Ruby")
    @name = myname
  end
  def hello
    puts "Hello, world. I am #{@name}."
  end
end
bob = HelloWorld.new("Bob")
alice = HelloWorld.new("Alice")
ruby = HelloWorld.new

bob.hello

类方法

class << HelloWorld
  def hello(name)
      puts "#{name} said hello."
  end
end

## 或者

class HelloWorld
  class << self
    def hello(name)
        puts "#{name} said hello."
    end
  end
end

## 或者

class HelloWorld
  def self.hello(name)
      puts "#{name} said hello."
  end
end
  • initialize方法相当于Python里的__init__
  • @name实例变量
  • @@count类变量是该类所有实例的共享变量

public, private and protected

class AccTest
  def pub
    puts "pub is a public method."
  end
  public :pub
  def priv
    puts "priv is a private method."
  end
  private :priv
end

acc = AccTest.new
acc.pub
acc.priv

类与对象判断

### 判断某个对象是否属于某个类时
ary = []
str = "Hello world."
p ary.instance_of?(Array)
p str.instance_of?(String)
p ary.instance_of?(String)
p str.instance_of?(Array)

### 根据类的继承关系反向追查对象是否属于某个类
str = "This is a String."
p str.is_a?(String)  
p str.is_a?(Object)  

模块 module

创建模块

module HelloModule
  Version = "1.0"           # 定义常量
  def hello(name)           # 定义方法
    puts "Hello, #{name}."
  end
  module_function :hello    # 指定hello方法为模块函数
end

p HelloModule::Version      #=> "1.0"
HelloModule.hello("Alice")  #=> Hello, Alice.

include HelloModule         # 包含模块
p Version                   #=> "1.0"
hello("Alice")              #=> Hello, Alice.