ror:Rails背后的Ruby

ror:Ruby on Rails

导言

承接前文!
本部分涉及的内容主要为Ruby基础,相对简单,所以只贴代码并加上了注释,不对代码进行详细解释

前方高能,保护眼睛。

创建并切换分支

git checkout -b rails-favored-ruby

自定义辅助方法

辅助方法定义在app/helper目录下的文件中:

# app/helper/application_helper.rb

module ApplicationHelper

    def full_title(page_title = '')
        base_title = "Microblog"
        if page_title.empty?
            base_title
        else
            page_title + " | " + base_title
        end
    end
end

此时,可将标题代码改为:

# app/views/layouts/application.html.erb

... ...
<%= full_title(yield(:title)) %>
... ...

合并分支

git checkout master
git merge rails-flavored-ruby
git branch -d rails-flavored-ruby 
git branch

字符串和方法

使用Rails控制台rails c或者使用irb --simple-prompt命令进行交互

注释

# single-line comment.  # 单行注释

=begin
multiple-lines comments.  # 多行注释
=end

双引号字符串

➜  microblog git:(rails-flavored-ruby) rails c
Running via Spring preloader in process 14069
Loading development environment (Rails 5.0.1)
2.3.3 :001 > "Hello, " + "Joshua"  # 字符串连接
 => "Hello, Joshua" 
2.3.3 :002 > name = "Joshua"  # 字符串赋值
 => "Joshua" 
2.3.3 :003 > "Hello, #{name}"  # 字符串插值
 => "Hello, Joshua" 
2.3.3 :004 > print "Joshua"  # 打印字符串(不换行,返回nil)
Joshua => nil 
2.3.3 :005 > puts "Joshua"  # 打印字符串(换行,返回nil)
Joshua
 => nil 
2.3.3 :006 > p "Joshua"  # 打印字符串(带双引号、换行,返回原字符串)
"Joshua"
 => "Joshua" 
2.3.3 :007 > (p "Joshua").length  # 进行级联操作
"Joshua"
 => 6 
2.3.3 :008 > (puts "Joshua").nil?  # 返回nil
Joshua
 => true

单引号字符串

2.3.3 :001 > 'Joshua'  # 字符串创建
 => "Joshua" 
2.3.3 :002 > "Hello, " + 'Joshua'  # 单引号字符串与双引号字符串类似
 => "Hello, Joshua" 
2.3.3 :003 > name = 'Joshua'  # 单引号字符串赋值
 => "Joshua" 
2.3.3 :004 > '#{name}'  # 不能进行插值
 => "\#{name}" 
2.3.3 :005 > '\n'  # 单引号字符串就是字面量,不进行转义
 => "\\n" 
2.3.3 :006 > '\''  # 只有单引号需要转义
 => "'" 

字符串基本用法见上述代码注释

流程控制/方法定义

参考本人的这篇文章。

数组和值域

数组

2.3.3 :001 > a = [1,2,3,4,5]  # 数组定义
 => [1, 2, 3, 4, 5] 
2.3.3 :002 > a.first  # 取第一个,相当于a[0]
 => 1 
2.3.3 :003 > a.third  # a[2]
 => 3 
2.3.3 :004 > a.fifth  # a[4]
 => 5 
2.3.3 :005 > a.length  # 数组长度
 => 5 
2.3.3 :006 > a.empty?  # 数组是否为空
 => false 
2.3.3 :007 > a[1]  # 数组取值
 => 2 
2.3.3 :008 > a[-1]  # 数组从后取值
 => 5 
2.3.3 :009 > a.last  # 最后一个值,相当于a[-1]
 => 5 
2.3.3 :010 > a.include?(3)  # 数组是否包含
 => true 
2.3.3 :011 > a.shuffle  # 数组置乱
 => [3, 4, 1, 2, 5] 
2.3.3 :012 > a.sort  # 数组排序
 => [1, 2, 3, 4, 5] 
2.3.3 :013 > a.reverse  # 数组逆序
 => [5, 4, 3, 2, 1] 
2.3.3 :014 > a.shuffle  # 置乱
 => [1, 2, 5, 4, 3] 
2.3.3 :015 > a  # 原数组不变
 => [1, 2, 3, 4, 5] 
2.3.3 :016 > a.shuffle!  # 带有!的表示破坏原数组
 => [1, 5, 3, 4, 2] 
2.3.3 :017 > a  # 原数组变了
 => [1, 5, 3, 4, 2] 
2.3.3 :018 > a.push(8)  # 插入值
 => [1, 5, 3, 4, 2, 8] 
2.3.3 :019 > a << 9  # 插入值
 => [1, 5, 3, 4, 2, 8, 9] 
2.3.3 :020 > a << "Hello" << "Joshua"  # 连续插入(不同类型)
 => [1, 5, 3, 4, 2, 8, 9, "Hello", "Joshua"] 
2.3.3 :021 > a.join  # 合成一个数组
 => "1534289HelloJoshua" 
2.3.3 :022 > a.join ','  # 使用,分隔合成数组
 => "1,5,3,4,2,8,9,Hello,Joshua"
2.3.3 :023 > a.join(',').split(',')  # 使用split分割为数组
 => ["1", "5", "3", "4", "2", "8", "9", "Hello", "Joshua"] 

数组基本用法见上述代码注释,比较简单不再赘述。

值域(Range)

2.3.3 :001 > 1..5  # 创建值域
 => 1..5 
2.3.3 :002 > (1..5).to_a  # 转变为数组
 => [1, 2, 3, 4, 5] 
2.3.3 :003 > (1...5).to_a  # ...表示忽略末尾
 => [1, 2, 3, 4] 
2.3.3 :004 > a = %w[foo bar baz quux hello joshua]  # 创建字符串数组
 => ["foo", "bar", "baz", "quux", "hello", "joshua"] 
2.3.3 :005 > a[1..4]  # 使用值域获取数组
 => ["bar", "baz", "quux", "hello"] 
2.3.3 :006 > a[1...4]  # 同样的道理
 => ["bar", "baz", "quux"]
2.3.3 :007 > a[2..-1]   # 使用-1结尾表示到数组最后
 => ["baz", "quux", "hello", "joshua"] 
2.3.3 :008 > a[2...-1]
 => ["baz", "quux", "hello"] 
2.3.3 :009 > a[2...(a.length-1)]  # 与-1相同
 => ["baz", "quux", "hello"] 
2.3.3 :010 > ('a'..'f')  # 使用字符创建值域
 => "a".."f" 
2.3.3 :011 > ('a'..'f').to_a  # 转变为数组
 => ["a", "b", "c", "d", "e", "f"] 

练习

在逗号和空格处分拆字符串“A man, a plan, a canal, Panama”,把结果赋给变量 a
不指定连接符,把 a 连接起来,然后把结果赋值给变量 s 。
在空白处分拆 s ,然后再连接起来。使用以下代码中的方法确认得到的结果不是回文。使用downcase 方法,确认 s.downcase 是回文。

def palindrome_tester(s)
if s == s.reverse
puts "It's a palindrome!"
else
puts "It's not a palindrome."
end
end


代码如下:

a = "A man, a plan, a canal, Panama".split ', '
s = a.join
str = s.split.join

palindrome_tester str
palindrome_tester str.downcase


## 块

2.3.3 :001 > (1..3).each { |i| p i ** 2 } # 使用each方法,传递块(**表示幂)
1
4
9
=> 1..3
2.3.3 :002 > (1..3).each do |i| # 等价使用方式
2.3.3 :003 > p i ** 2
2.3.3 :004?> end
1
4
9
=> 1..3

常用的约定:

当块只有一行简单的代码时使用花括号形式

当块是一行很长的代码,或者有多行时使用 do..end 形式

2.3.3 :005 > 3.times { p "My name is Joshua" } # 循环多次
"My name is Joshua"
"My name is Joshua"
"My name is Joshua"
=> 3
2.3.3 :006 > (1..5).map { |i| i*2 } # map返回块中操作后的结果数组
=> [2, 4, 6, 8, 10]
2.3.3 :007 > %w[a b c].map { |c| c.upcase } # 同样
=> ["A", "B", "C"]
2.3.3 :008 > %w[a b c].map &:upcase # 可以简写为这样,不好理解
=> ["A", "B", "C"]


#### 练习
创建值域 0..16,把前 17 个元素的平方打印出来。

(0..16).each { |number| p number ** 2 }


定义一个名为 yeller 的方法,它的参数是一个由字符组成的数组,返回值是一个字符串,由数组中字符的大写形式组成。确认 yeller([’o’, ’l’, ’d’]) 的返回值是 OLD 。提示:要用到 map 、upcase 和 join 方法。

def yeller(arr)
arr.map(&:upcase).join
end


定义一个名为 random_subdomain 的方法,返回八个随机字母组成的字符串。

def random_subdomain
('a'..'z').to_a.shuffle[0..7].join
end


把下列代码中的问号换成正确的方法,结合 split 、 shuffle 和 join 方法,把指定字符串中的字符打乱。

def string_shuffle(s)
s.?('').?.?
end
string_shuffle("foobar")
"oobfra"

> 修改代码如下:
> 

def string_shuffle(s)
s.split('').shuffle.join
end


## 哈希和符号

2.3.3 :001 > user = {} # 创建空的哈希表
=> {}
2.3.3 :002 > user["name"] = "Joshua" # 设置值
=> "Joshua"
2.3.3 :003 > user["name"] # 取值
=> "Joshua"
2.3.3 :004 > user["password"] # 获取空值
=> nil
2.3.3 :005 > user # 显示
=> {"name"=>"Joshua"}
2.3.3 :006 > user = { "name" => "Joshua", "email" => "[email protected]" } # 创建非空的哈希表
=> {"name"=>"Joshua", "email"=>"[email protected]"}
2.3.3 :007 > user = { :name => "Joshua", :email => "[email protected]" } # 使用符号创建非空哈希表
=> {:name=>"Joshua", :email=>"[email protected]"}
2.3.3 :008 > user = { name: "Joshua", email: "[email protected]" } # 符号创建简写方式
=> {:name=>"Joshua", :email=>"[email protected]"}
2.3.3 :009 > user[:name]
=> "Joshua"
2.3.3 :010 > user[:email] = { netease: "[email protected]", gmail: "[email protected]" } # 嵌套哈希表
=> {:netease=>"[email protected]", :gmail=>"[email protected]"}
2.3.3 :011 > user
=> {:name=>"Joshua", :email=>{:netease=>"[email protected]", :gmail=>"[email protected]"}}
2.3.3 :012 > user.each do |key, value| # each遍历
2.3.3 :013 > p "Key: #{key}, Value: #{value}"
2.3.3 :014?> end
"Key: name, Value: Joshua"
"Key: email, Value: {:netease=>"[email protected]", :gmail=>"[email protected]"}"
=> {:name=>"Joshua", :email=>{:netease=>"[email protected]", :gmail=>"[email protected]"}}
2.3.3 :015 > user.each do |key, value| # inspect显示字面量
2.3.3 :016 > p "Key: #{key.inspect}, Value: #{value.inspect}"
2.3.3 :017?> end
"Key: :name, Value: "Joshua""
"Key: :email, Value: {:netease=>"[email protected]", :gmail=>"[email protected]"}"
=> {:name=>"Joshua", :email=>{:netease=>"[email protected]", :gmail=>"[email protected]"}}

**同样,用法见注释**

#### 练习
定义一个哈希,把键设为 'one' 、 'two' 和 'three' ,对应的值分别是 'uno' 、 'dos' 和 'tres' 。迭代这个哈希,把各个键值对以 "'#key' in Spanish is '#value'" 的形式打印出来。

ott = { "one" => "uno", "two" => "dos", "three" => "tres" }
ott.each do |key, value|
p "'#{key}' in Spanish is '#{value}'"
end


创建三个哈希,分别命名为 person1 、 person2 和 person3 ,把名和姓赋值给 :first 和 :last 键。然后创建一个名为 params 的哈希,让 params[:father] 对应 person1 , params[:mother] 对应 person2 ,params[:child] 对应 person3 。验证一下 params[:father][:first] 的值是否正确。

person1 = { first: "father_first", last: "father_last" }
person2 = { first: "mather_first", last: "mather_last" }
person3 = { first: "child_first", last: "child_last" }
params = { father: person1, mather: person2, child: person3 }
params[:father][:first]


定义一个哈希,使用符号做键,分别表示名字、电子邮件地址和密码摘要,把键对应的值分别设为你的名字、电子邮件地址和一个由 16 个随机小写字母组成的字符串。

info = { name: "Joshua", email: "[email protected]", password: ('a'..'z').to_a.shuffle[0..15].join }


找一个在线 Ruby API,查阅哈希的 merge 方法。下述表达式的值是什么?

{ "a" => 100, "b" => 200 }.merge({ "b" => 300 })

表示合并哈希,若键值重复则覆盖。

## Ruby类

#### 构造方法

2.3.3 :001 > str = "Joshua" # 构造字符串
=> "Joshua"
2.3.3 :002 > str.class # 获取类型
=> String
2.3.3 :003 > String.new("Joshua") # 使用类名构造对象
=> "Joshua"
2.3.3 :004 > str.class.new("Aber") # 同理
=> "Aber"
2.3.3 :005 > Array.new([1,2,3]) # 构造数组
=> [1, 2, 3]
2.3.3 :006 > Hash.new # 构造Hash
=> {}
2.3.3 :007 > h = Hash.new("Joshua") # 修改默认返回为Joshua
=> {}
2.3.3 :008 > h[:joshua]
=> "Joshua"
2.3.3 :009 > (1..10).class # 获取Range类型
=> Range
2.3.3 :010 > r = Range.new(1, 10) # 构造Range
=> 1..10
2.3.3 :011 > r == (1..10) # 证明相等
=> true


#### 类的继承

2.3.3 :001 > str = "Joshua"
=> "Joshua"
2.3.3 :002 > str.class.superclass
=> Object
2.3.3 :003 > str.class.superclass.superclass
=> BasicObject
2.3.3 :004 > str.class.superclass.superclass.superclass
=> nil

2.3.3 :005 > Hash.superclass
=> Object
2.3.3 :006 > Array.superclass
=> Object
2.3.3 :007 > Range.superclass
=> Object


2.3.3 :008 > class Word < String # 继承String
2.3.3 :009?> def palindrome?
2.3.3 :010?> self == self.reverse # self表示对象本身

继承了reverse方法,可以简写为self == reverse

2.3.3 :011?> end
2.3.3 :012?> end
=> :palindrome?
2.3.3 :013 > w = Word.new("abcba")
=> "abcba"
2.3.3 :014 > w.palindrome? # 自定义方法
=> true
2.3.3 :015 > w.length # 拥有父类方法
=> 5
2.3.3 :016 > w.class.superclass # 查看父类
=> String


#### 修改内置类

2.3.3 :001 > class String # 修改内置String类,添加功能
2.3.3 :002?> def palindrome?
2.3.3 :003?> self == reverse
2.3.3 :004?> end
2.3.3 :005?> end
=> :palindrome?
2.3.3 :006 > "abcba".palindrome?
=> true
2.3.3 :007 > class String # 再次修改
2.3.3 :008?> def shuffle
2.3.3 :009?> self.split('').shuffle.join
2.3.3 :010?> end
2.3.3 :011?> end
=> :shuffle
2.3.3 :012 > "joshuaber".shuffle
=> "rbhjoeaus"
2.3.3 :013 > "joshuaber".palindrome? # 之前添加的方法仍然可用
=> false
2.3.3 :014 >


#### 自定义类

关于类的定义及存取器的定义,参考[这里](http://www.jianshu.com/p/437d5f947427)。啥也不说了,看代码吧:

```ruby
class User
  attr_accessor :name, :email

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

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

user = User.new
p user
p user.name
user.name = "Joshua"
p user.name
user.email = "[email protected]"
p user.email
p user.format_user

juser = User.new(name: "Joshua", email: "[email protected]")
p juser.format_user

参考

《Rails Tutorial 4th》

你可能感兴趣的:(ror:Rails背后的Ruby)