您的位置:首页 > 大数据 > 人工智能

Rails读书笔记第四章

2015-10-12 03:27 513 查看

Ruby

在Ruby中,一切皆为object。构造函数是new。
在Ruby中括号是可选的,一般用于很长的表达式时才使用括号,像一般的类似命令或者声明的方法一般不用括号。
成员变量用@的前缀标明,用下划线来链接单词。类名、module名和常量通常是用首字母大写来链接单词。
symbol用来命名方法的参数和hash中的key,用:前缀标明。你可以理解成symbol是转化成常量的字符串(internalized constant string),或者是the thing named XX.
方法的定义用def end,最后一个表达试的值就是函数的返回值。
String类:有两种,一种是用单引号' '标记的,一种是用双引号“ ”标记的。用单引号标记的内容不经处理直接赋值,而用双引号标记的内容会先找到转义字符并把其转换成二进制值,然后会将#{ }引用的内容解析出来。
nil也是一个object,用来represent nothing。nil的boolean值为false,而正常的object的boolean值为true。

Array和Hash

Array和Hash都是indexed collection,自适应大小,能够存不同类型的数据。
通常使用<<来向矩阵添加元素。
创造单词矩阵时有捷径:
a = %w{ ant bee cat }
使用symbol在hash中定义key有两种方法:
hashtable1 = {
:symbol1 => 'Haha'
:symbol2 => 'Heihei'
}

hashtable2 = {
symbol1: 'Haha'
symbol2: 'Heihei'
}
第一种方法适用于任何情况,第二种只适合symbol。
在访问时使用hashtable1[:symbol1]即可。
hash可以作为方法的参数传入,如果hash是最后一个参数的话,{}括号可以省略:
redirect_to action: 'show', id: product.id
上面这个redirect_to命令传入了两个hash,一个是key为:action值为'show',另一个是key为:id值为product.id。

正则表达式:

可以写成/pattern/,或则是%r{pattern}。~/pattern/是说不包含这个pattern的结果。
A|B是两者都可以,A+是至少有一个,A*是可有可无。
\d是digit,\s是空格\tab,\w是word。

Block

可以用{},也可以是do ... end。可传给方法,如果方法有参数,则把block写在最后。
hello('Geurney') {puts 'Hi'}
block会在函数的yield的地方执行,可以给block传参数,例如:
animals.each {|animal| puts animail }

让block执行多次:
3.times {puts 'Hi'}
如果让block作为函数参数时,在定义函数时要使用&:
def hello &block
3.times(&block)
end
在调用函数时使用:
hello {puts 'Hi'}


异常处理

使用raise方法抛出异常,将会抛出异常的方法放在begin...end中,用rescue来捕获异常:
begin
content = load_blog_data(file_name)
rescue BlogDataNotFound
STDERR.puts "File #{file_name} not found"
rescue BlogDataFormatError
STDERR.puts "Invalid blog data in #{file_name}"
rescue Exception => exc
STDERR.puts "General error loading #{file_name}: #{exc.message}"
end

也可以在方法中直接使用:

rescue StandardError => e可以简写为:
rescue => e

class Order < ActiveRecord::Base
has_many :line_items

def self.find_all_unpaid
self.where( 'paid = 0' )
end
def total
sum = 0
line_items.each {|li| sum += li.total}
sum
end
end在上面这个例子,定义了Order这个类,这个类继承自来自ActiveRecord module 的Base类。在一个module可以定义很多类。::这里来确定命名空间。
has_many是ActiveRecord module里的方法,传入了一个:line_items的参数。has_many方法在Order类定义时被调用,像这样在类定义时调用的class-level的方法称为declaration。

用self作前缀的方法是类方法,类方法只能通过类名调用。在类方法中,访问成员变量不报错但是没有值,self指代的是类。

非类方法默认是public,self指代的是instance。

使用@定义的成员变量只能在类内访问,如果要在类外访问,需要定义方法,或者使用attr定义:

class Greeter
def initialize(name)
@name = name
end

def name
@name
end

def name=(new_name)
@name = new_name
end
end上面是用方法定义的getter和setter。
class Greeter
attr_accessor :name
attr_reader :greeting
attr_writer :age这里使用attr_accessor定义了getter和setter,greeting只提供了getter,而age只提供了setter。
即可以使用.greeting来访问greeting的内容,使用.age=(17)来设置age的值。

注意这里的成员变量不是symbol,因为symbol是常量。没有用@标志的变量是局部变量。注意使用.to_s等类型转换。

@@标记的是类变量。

Access Control

public方法可以在类外访问

private方法只能在类内使用,使用时只能implicitly,不能使用self.来explicitly调用,不能调用其他instance的private方法(区别于protected方法)。

def hello
hi #OK
self.hi #Not OK
end

private
def hi
endprotected方法只能在类内使用,使用时可以explicitly指明是在哪个instance上调用,如果是implicitly相当于是self的explicitly。
def compare(another_instance)
self.age.to_i > another_instance.age.to_i
end

protected
def age
@age
end上面定义了age方法是protected的,在compare方法中传入了另一个instance,可以用调用self的age方法也可以,调用另一个instance的age方法。
将accessor设置为protected或private:
class Test
attr_accessor :age
protected :age
end上述定义了成员变量age,然后将age的accessor定义为了protected。好像只能这样使用该语法。

module

module可以包含方法、常量、module和类定义。但module不能被实例化。module可以提供namespace和功能。

Rails可以自动将helper module和对应的view template链接起来。例如你写了一个helper的方法,你想在你的controller中控制view时调用这个方法,你就可以将你的helper方法加入到app/helpers目录下对应controller的ControllerHelper.rb文件中。

YAML是ruby library的一个module,用来写数据库、测试数据等的配置文件,文件后缀名为yml。例如:

development:
adapter: sqlite3
database: db/development.sqlite3
pool: 5
timeout: 5000yml文件需要注意缩进,存储的是key/value pair。

最后一个例子

class CreateProducts < ActiveRecord::Migration
def change
create_table :products do |t|
t.string :title
t.text :description
t.string :image_url
t.decimal :price, precision: 8, scale: 2
t.timestamps
end
end
end上面定义了CreateProducts类,这个类继承自ActiveRecord module的Migration类,定义了一个change方法。这个方法调用了Migration的create_table类方法,将一个products的table以symbol的形式作为参数,并提供了一个block。当这个block被调用时,将一个object传给了t,然后依次定义t的各个field,如:title、:description等。而t.decimal 还传入了两个hash作为参数,一个是precision=>8,一个是scale=>2。

或运算

a||b,如果a不为nil或者false,则返回a。否则返回b

a ||= b,如果a没有被赋值,则赋值为b,否则还是a。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: