Rails读书笔记第四章

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
end
protected方法只能在类内使用,使用时可以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: 5000
yml文件需要注意缩进,存储的是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。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值