欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Ruby 元编程 第二版随笔(一)

程序员文章站 2022-07-15 20:07:23
...

 

 

   目标:建立一个存放电影名和影评的数据库,因此决定创建一个简单的代码库,用于在数据库中实现对象的持久化。

   第一次尝试:编写一个代码库,把数据库中的每个表映射到一个类中,同时把每条记录映射到对象中,每当创建一个对象或访问它的属性时,这个对象就会产生一条SQL语句并发送给数据库。所有的这些功能都封装在一个类里面。

 

   

classs Entity
  attr_reader :table, :ident
  def initialize(table, ident)
    @table = table
    @ident = ident
    Database.sql "INSERT INTO #{@table}  (id)  VALUES (#{@ident})" 
  end

  def set(col, val)
    Database.sql "UPDATE #{@table} SET #{col}='#{val}' WHERE id=#{@ident}"
  end

  def get(col)
    Database.sql ("SELECT #{col} FROM #{@table} WHERE id=#{@ident}") [0][0]
  end
end

 

  在数据库中,每个表都有一个id字段,每个Entity 会保存这个字段的内容以及它 的表名。创建一个Entity 对象后, 该对象会把自己保存在数据库中,Entity#set 方法会创建SQL语句更新字段的值, 而Entity#get 方法创建SQL语句读取字段的值。database使用数组的数组作为返回的数据集。

 

     我们可以继承Entity类来映射一个指定的表。 例如, 用Movie类映射一个名为movies 的表:

 

class Movie < Entity
  def initialize(ident)
    super "movies", ident
  end

  def title
    get "title"
  end

  def title=(value)
    set "title", value
  end

  def director
    get "director"
  end

  def director=(value)
    set "director", value
  end
end

 

     Movie 类 的每个属性有两个方法: 一个像Movie#title这样的reader方法和一个像Movie#title=这样的writer方法。只要在Ruby命令行解释器里边输入命令就可以把一部电影加载到数据库里。

 

 

movie = Movie.new(1)
movie.title = "SuperMan"
movie.director = "Stabley Kubrick"

 

 

   但是Ruby 中有一个非常强大的类库 Active Record 可以吧对象映射到数据表中,

   那么用Active Record 写出来的Movie类是什么样子呢?

   Movie类:

   

class Movie < ActiveRecord::Base
end

 

 

   OK 就这么简单 ,我们只是从Active Record ::Base继承了一个子类,它不用指定用那个表来映射Movie对象,也不用title和director这些看起来差不多的方法。程序会照样工作。

 

movie = Movie.create
movie.title = "SuperMan"
movie.title                         # => "SuperMan"

 

 

    上面代码创建了一个Movie对象,该对象包装了movies表中的一条记录。然后通过Movie#title和Movie#title=方法访问title字段。这是如何实现的呢, 这和Active Record  的工作原理有关。

    Active Record 通过内省机制查看类的名字。因为类名是Movie,Active Record 会自动把它映射到movies 的表中。(它知道如何转换英文单词的单复数。)

   那么,像title和title=这样的方法(简称为访问器)又是怎样处理的呢? 这就是元编程的妙用了。Active Record 会自动定义这些方法。Active Record ::Base在运行时读取数据库的表模式,找到movies表有两个名为title和director 的字段,然后自动定义两个同名的属性和响应的访问器。也就是说,Active Record 在程序运行时动态的创建了Movie#title和Movie#director=这样的方法。

 

  Ruby 不但可以在运行时访问语言构件,还能够修改他们。是不是很神奇呢?

 

 

相关标签: ruby 元编程