Ruby 基础语法

在 Ruby 中,一切皆对象,包括字符串和 nil 都是。

字符串

"foo" + "bar"    # 字符串拼接
=>  "foobar"

first_name = "Michael"    # 变量赋值
"#{first_name} Hartl"     # 字符串插值 #{变量名}
=> "Michael Hartl"

# 关于单双引号
Ruby 不会对单引号字符串进行插值操作
 "foobar".length        # 获取字符串长度
=> 6

ruby中自带函数

# 是否为空   empty? 方法
# 注意,empty? 方法末尾有个问号,这是 Ruby 的约定,说明方法返回的是布尔值,即 true 或 false。

"foobar".empty?
=> false
"".empty?
=> true

# if else 用法
if s.nil?
   "The variable is nil"
elsif s.empty?
   "The string is empty"
elsif s.include?("foo")
   "The string includes 'foo'"        # 是否包含 'foo'
end
=> "The string includes 'foo'"

#  &&(与)、||(或)和 !(非)运算符
x = "foo"
y = ""
puts "Both strings are empty" if x.empty? && y.empty?
=> nil
puts "One of the strings is empty" if x.empty? || y.empty?
=> "One of the strings is empty"
=> nil
puts "x is not empty" if !x.empty?
=> "x is not empty"
=> nil

# to_s 方法基本上可以把任何对象转换成字符串
nil.to_s
=> ""

nil.empty?
NoMethodError: undefined method `empty?` for nil:NilClass
nil.to_s.empty?      # 消息串联
=> true

# 测试对象是否为空
"foo".nil?
=> false
"".nil?
=> false
nil.nil?
=> true
# if 关键词 用法 表达式为真值时才执行的语句
# 还有个对应的 unless 关键字也可以这么用
puts "x is not empty" if !x.empty?

string = "foobar"
puts "The string '#{string}' is nonempty." unless string.empty?

nil 对象的特殊性,除了 false 本身之外,所有 Ruby 对象中它是唯一一个布尔值为“假”的。
我们可以使用 !!(读作“bang bang”)对对象做两次取反操作,把对象转换成布尔值:

!!nil
=> false

除此之外,其他所有 Ruby 对象都是“真”值,数字 0 也是:

!!0
=> true

数组

# 字符串转为数组 split     
 "foo bar     baz".split     # 把字符串拆分成有三个元素的数组
=> ["foo", "bar", "baz"]

# 根据字符 转化
"fooxbarxbazx".split('x')
=> ["foo", "bar", "baz"]

a = [42, 8, 17]
a[0]               # Ruby 使用方括号获取数组元素
=> 42
a[-1]              # 索引还可以是负数
=> 17
a.first
=> 42
a.second
=> 8
a.last == a[-1]    # 用 == 运算符对比  != | > | < | <= | >=
=> true

# 求数组长度
x = a.length       # 和字符串一样,数组也可以响应 length 方法
=> 3

a.empty?
=> false
a.include?(42)      # 是否存在42这个值
=> true
a.sort              # sort 升序排序
=> [8, 17, 42]
a.reverse           # 数组反转 | 字符串反转 也是这个
=> [17, 8, 42]
a.shuffle           # shuffle 随机排序
=> [17, 42, 8]

# 修改数组中值的顺序[改变key值],加上 !
a.sort!

# 向数组中追加元素
a.push(6)                  # 把 6 加到数组末尾
=> [42, 8, 17, 6]
a << 7                     # 把 7 加到数组末尾
=> [42, 8, 17, 6, 7]
a << "foo" << "bar"        # 串联操作
=> [42, 8, 17, 6, 7, "foo", "bar"]

# join 数组转化为字符串 与 split 相反
a.join                       # 没有连接符
a.join(', ')                 # 连接符是一个逗号和空格

值域

# 值域(range)
0..9

# 转为数组 to_a 
(0..9).to_a            # 调用 to_a 时要用括号包住值域
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# 值域也可以使用字符串定义
('a'..'e').to_a
=> ["a", "b", "c", "d", "e"]
# 值域经常用于获取数组的一组元素
a = %w[foo bar baz quux]          #  %w 创建一个元素为字符串的 数组
=> ["foo", "bar", "baz", "quux"]
a[0..2]
=> ["foo", "bar", "baz"]

# 获取2至数组最后一位的元素
a[2..(a.length-1)]               # 显式使用数组的长度
=> [2, 3, 4, 5, 6, 7, 8, 9]
a[2..-1]                         # 小技巧,索引使用 -1
=> [2, 3, 4, 5, 6, 7, 8, 9]

# 遍历
(1..5).each { |i| puts 2 * i }
2
4
6
8
10
=> 1..5
# 说明 -------
在值域 (1..5) 上调用 each 方法,然后又把 { |i| puts 2 * i } 这个块传给 each 方法。
|i| 两边的竖线在 Ruby 中用来定义块变量。只有方法本身才知道如何处理后面跟着的块。
这里,值域的 each 方法会处理后面的块,块中有一个局部变量 i,each 会把值域中的各个值传进块中,
然后执行其中的代码。
花括号是表示块的一种方式,除此之外还有另一种方式:
# ------------

(1..5).each do |i|
   puts 2 * i
end

# 结果和上面的一样

## 块中的内容可以多于一行,而且经常多于一行。
## 当块只有 一行简单的代码时 使用 花括号 形式;
## 当块是一行很长的代码,或者有多行时使用 do..end 形式:

(1..5).each do |number|
   puts 2 * number
   puts '-'
end
# 其他遍历
3.times { puts "Betelgeuse!" }   # 3.times 后跟的块没有变量
"Betelgeuse!"
"Betelgeuse!"
"Betelgeuse!"
=> 3
(1..5).map { |i| i**2 }          # ** 表示幂运算
=> [1, 4, 9, 16, 25]
%w[a b c]                        # 再说一下,%w 用于创建元素为字符串的数组
=> ["a", "b", "c"]
%w[a b c].map { |char| char.upcase }
=> ["A", "B", "C"]
%w[A B C].map { |char| char.downcase }
=> ["a", "b", "c"]

# 简写
%w[A B C].map(&:downcase)
=> ["a", "b", "c"]

散列[关联数组]和符号

user = {}                          # {} 是一个空散列
=> {}
user["first_name"] = "Michael"     # 键为 "first_name",值为 "Michael"
=> "Michael"
user["last_name"] = "Hartl"        # 键为 "last_name",值为 "Hartl"
=> "Hartl"
user["first_name"]                 # 获取元素的方式与数组类似
=> "Michael"
user                               # 散列的字面量形式
=> {"last_name"=>"Hartl", "first_name"=>"Michael"}

#  => 创建散列
user = { "first_name" => "Michael", "last_name" => "Hartl" }
=> {"last_name"=>"Hartl", "first_name"=>"Michael"}
# 在 Rails 中用符号(Symbol)做键很常见。符号看起来有点儿像字符串,只不过没有包含在一对引号中,
# 而是在前面加一个冒号。例如,:name 就是一个符号。你可以把符号看成没有约束的字符串
# 符号是 Ruby 特有的数据类型.

user = { :name => "Michael Hartl", :email => "[email protected]" }
=> {:name=>"Michael Hartl", :email=>"[email protected]"}

user[:name]              # 获取 :name 键对应的值
=> "Michael Hartl"

user[:password]          # 获取未定义的键对应的值
=> nil

# 散列的第二种表示方式
{ name: "Michael Hartl", email: "[email protected]" }

# 在散列字面量中,:name => 和 name: 作用一样。
# 如果要表示符号,只能使用 :name(冒号在前面)。
# 嵌套散列
params = {}        # 定义一个名为 params(parameters 的简称)的散列
=> {}
params[:user] = { name: "Michael Hartl", email: "[email protected]" }
=> {:name=>"Michael Hartl", :email=>"[email protected]"}
params
=> {:user=>{:name=>"Michael Hartl", :email=>"[email protected]"}}
params[:user][:email]
=> "[email protected]"
# 散列响应遍历
flash = { success: "It worked!", danger: "It failed." }
flash.each do |key, value|
   puts "Key #{key.inspect} has value #{value.inspect}"
end
# inspect 方法,它的作用是返回被调用对象的字符串 字面量 表示形式

# String 
# 字面构造方法
s = "foobar"       # 使用双引号字面构造方法
=> "foobar"
s.class            # 响应class方法,返回所属的类
=> String

#具名构造方法
s = String.new("foobar")   # 字符串的具名构造方法
=> "foobar"
s == "foobar"
=> true
# Array
# 数组的构造方法 Array.new 可接受一个可选的参数指明数组的初始值
a = Array.new([1, 3, 2])
=> [1, 3, 2]
# Hash[散列]
h = Hash.new
=> {}
h[:foo]            # 试图获取不存在的键 :foo 对应的值
=> nil
h = Hash.new(0)    # 让不存在的键返回 0 而不是 nil
=> {}
h[:foo]
=> 0
# 不继承其他类
class Word
   def palindrome?(string)
     string == string.reverse
   end
end
# 调用
w = Word.new              # 创建一个 Word 对象
w.palindrome?("foobar")
=> false
w.palindrome?("level")
=> true

########################

# 继承 String 类
class Word < String             # Word 继承自 String
   # 如果字符串和反转后相等就返回 true
   def palindrome?
     self == self.reverse        # self 代表这个字符串本身
     # 其实,在类中调用方法或访问属性时可以不用 self.(赋值例外),因此也可以写成
     # self == reverse
   end
end
# 调用
s = Word.new("level")    # 创建一个 Word 实例,初始值为 "level"
s.palindrome?            # Word 实例可以响应 palindrome? 方法
=> true
s.length                 # Word 实例还继承了String的所有方法
=> 5

# 查找 s 的父类
s.class.superclass             
s.class.superclass.superclass  # Ruby 1.9 使用 BasicObject 作为基类
# blank?  检查是否为空字符串
"".blank?
=> true
"   ".empty?
=> false
"   ".blank?
=> true
nil.blank?
=> true
# 一个包含空格的字符串不是空的(empty),却是空白的(blank)。
# 还要注意,nil 也是空白的。因为 nil 不是字符串
class User
  # 创建属性访问器存取方法
  # 定义读值方法(getter)和设值方法(setter),用于读取和设定 @name@email 实例变量
  attr_accessor :name, :email

  def initialize(attributes = {})
    @name  = attributes[:name]
    @email = attributes[:email]
  end

  def formatted_email
    "#{@name} <#{@email}>"
  end
end

需要注意的:

// 在 Ruby 中,括号是可以省略的
// 调用函数时可以省略括号
stylesheet_link_tag('application', media: 'all',
                                   'data-turbolinks-track': 'reload')
stylesheet_link_tag 'application', media: 'all',
                                   'data-turbolinks-track': 'reload'

// 调用函数时,如果散列是最后一个参数,可以省略花括号
stylesheet_link_tag 'application', { media: 'all',
                                     'data-turbolinks-track': 'reload' }
stylesheet_link_tag 'application', media: 'all',
                                   'data-turbolinks-track': 'reload'

参考:
https://railstutorial-china.org/book/chapter4.html
https://www.railstutorial.org/book/rails_flavored_ruby

你可能感兴趣的:(ruby)