Cantin's blog

......

Function Js

| Comments

object

在js中object就是key: value的集合。

function对象也是object对象,但是他们都是以function关键字定义滴。

1
2
  Object //function Object() {};
  Function //function Function() {};

每一个object里面都会有个constructor的key,value一般就是object的function引用。 例如:

1
2
 var o = new Obkect();
 o.constructor // function Object() {}

function, new 与Object, Function

function与Function是不同的,function是关键字,而Function是对象。

1
2
3
function s() { this.qq = 'ss' }
s  //function s() { this.qq = 'ss' }
s.constructor // function Function() {}

所有的function对象都是由Function这个对象创建出来的。

1
2
 function s() { this.qq = 'ww' };
 var o = new s();

与下面代码应该相等:

1
2
3
4
5
 function s() { this.qq = 'ww' }
 var o = {};
 s.call(0)
 o.constructor = s
 0.__proto__ = s.prototype
1
2
3
 function s() { this.qq = 'asd' };
 s.call(s);
 s.qq;     // 'asd'

proto

object都有proto属性,其中保存着constructor的prototype

1
2
3
4
5
 //在chrome下
 function s() {}
 s.__proto__  // function Empty() {}
 Function.prototype // function Empty() {}
 Function.__proto__ // function Empty() {}

prototype

function对象的属性存放处

function, object

object拥有constructor,proto属性 function除了拥有上述属性,还拥有prototype属性,还拥有call,apply方法

后记

写的还真烂······

Spork Reload Model

| Comments

spork的问题

使用spork1.0.0rc2在为测试加速时,并不会每次都reload model。 也就是说,使用spork时,如果你model有了一丝改变,那就需要重启spork。 老实说,这相当不方便。

解决方法1

(使用的是rspec)在spec_helper.rb里面添加如下代码:

1
2
3
4
5
6
7
Spork.each_run do
  require 'factory_girl_rails'
  # reload all the models
  Dir["#{Rails.root}/app/models/**/*.rb"].each do |model|
    load model
  end
end

解决方法2

前提是使用rspec与factory_girl_rails 在gemfile里面添加:

1
gem 'factory_girl_rails', require: false

在spec_helper.rb里添加:

1
2
3
Spork.each_run do
  require 'factory_girl_rails'
end

Monkeypatch With Hash and Array

| Comments

前言

几个月前,工作中需要判断一个一个hash中是否包含了另一个hash/array(在更深层次上), 但ruby中没有提供这样的方法,所以在涛哥的指导下,我写了下列两个方法来 实现这个功能

array

array的方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Array
  def contains? array
    array.each do |value|
      flag = false
      self.each do |v|
        if  value.class == v.class && v.respond_to?(:contains?)
          flag = true if v.contains?(value)
        else
          flag = true if v == value
        end
      end
      return false unless flag
    end

    true
  end
end

hash

hash的方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Hash
  def contains?(hash)
    hash.each do |key, value|
      return false unless include?(key)

      if value.respond_to?(:contains?)
        return false unless self[key].contains?(value)
      else
        return false unless value == self[key]
      end
    end

    true
  end
end

后记

第一次写ruby的extsion,印象还是很深刻的。

Generator on Rails

| Comments

前言

generator在rails开发中是十分好用的工具, 今晚看了一下rails的generator,闲来无事便将基本的记下来。

guides的链接为http://guides.rubyonrails.org/generators.html

rails3.0以后的generator是建立在Thor这个gem上的,github的链接为https://github.com/wycats/thor

生成generator

进入rails项目,在终端下输入下列命令:

1
rails generate generator generator_name

生成文件如下:

1
2
3
/lib/generator/generator_name/USAGE
/lib/generator/generator_name/generator_name.rb
/lib/generator/generator_name/templates/

其中generator_name.rb中是执行generate命令时运行的文件, USAGE是这个generator的说明, templates目录下是执行这个generator是需要用到的文件,可在generator_name.rb中改变

若generator_name.rb中有copy_file这个方法 当执行generator命令时,此方法会找到templates下的相应文件copy到rails项目中

具体可以参考guides

配置generator

在rails中可以在config/applications.rb配置generator,如下:

1
2
3
4
5
config.generators do |g|
  g.orm             :active_record
  g.template_engine :erb
  g.test_framework  :test_unit, :fixture => true
end

后记

目前还未有用到generator的机会,所以写的实在不是很详细,等以后再来完善吧。

Js与observer

| Comments

前言

放假的晚上,窝在宿舍,懒懒的。无聊之余就想写一下之前学过的 javascript的observer,免得自己将来真的忘了。

ps:现在真的快忘了。。。。

javascript与observer

为什么需要observer

在编写js的时候,通常会遇到这样的问题。js中的数据与页面的数据需要保持一致. 比如说在js中的一个model,当它发生改变时,页面上对应的数据必须发生改变。 如果不使用observer的话,我们可能需要自己手动的在方法中调用。这样会导致model 与view的代码紧耦合。一旦需求变动,将很难改动。在这种情况下,我们可以使用observer来 解决这个问题。通过model的注册事件,一旦发生事件,对应的view的代码便会执行,从而达到 一致的目的。

observer的用法

Event对象

首先,我们需要一个Event对象来存放事件触发后执行的handler与它的scope。

event构造如下:

1
2
3
4
5
  function Event(handler, scope, options) {
    this.handler = handler;
    this.scope = scope;
    this.options = options;
  }

model的写法

在model中,需要有属性如下:

1
2
3
4
5
6
 function Model(options) {
  var event = ["add", "remove", "update"];
  var listener = {};

  ....
 }

其中event为数组,存放着当model的事件,当这些事件触发时,会调用listener中对应数组的event对象。 listener是存放event对象的一个对象(或者近似的认为是hash)。 在model里还需要有如下方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
  Model.pototype = {
    add: function() {
      .....

      // at the end
      this.fireEvent('add')
    }

    on: function(event, handler, scope, options) {
      if(this.hasEvent(event)){
        var e = new Event(handler, scope, options);

        if(!this.listener[event]){
          this.listener[event] = new Array();
        }

        this.listener[event].push(e);
      }
    },

    //private
    fireEvent: function(event) {
      if(this.hasEvent(event)){
        for(var i = 0; i < this.listener[event].length; i++){
          var e = this.listener[event][i];
          e.handler.call(e.scope, options)
        }
      }
    },

    //private
    hasEvent: function(event) {
      for(var i = 0; i < this.event.length; i++){
        if(this.event[i] == event) {
          return true;
        }
      }
      return false;
    }
  }

其中private表示此方法不对外提供, hasEvent是为了判断传入的事件是否是model中注册的事件, fireEvent是在model在内部调用,用以调用在view在model注册的handler, on是提供对外的接口,用来让view调用,注册view的handler, add是model事件函数示例,在让model发生改变的方法中的最下面调用fireEvent,从而达到调用handler的目的。

ps:不负责任的说,Event对象的options参数是我在写这篇文章时候才加进去的,没有经过任何测试,哇哈哈。

ps:再不负责的说,上述方法都是我凭印象写的,正确性应该是可以保证的吧····

view的写法

在view中我们需要向model中注册当model发生改变是自动执行的函数,也就是handler.

示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  function View(model) {
   this.model = model;
  }
  var model = new Model();
  var view = new View(model);

  view.addView = function() {
    //something for handle while model fire
    .....
  };

  view.addHandler = function() {
    this.model.on('add', addView, this);
  };

  view.addHandler();

view的写法有多种,大意就是调用model的on函数。

小结

observer的好处在于,当model(或者是其他对象)变化的时候,它能通知到其他注册在上面的对象也发生变化。 这样一方面是全部对象更新的很及时,另一方面是解耦了对象,model(被观察对象?)与view(观察对象?)只需要通过 model的几个函数交互,而不需要知道其他对象的实现细节,同时view可以注册多个handler到model中去,可扩展性比较好。

ps:我还是不知道model与view是谁观察谁·····

ps:文笔感觉还是很不行,见谅见谅。

Myql自定义配置

| Comments

mysql配置

在mac下默认是没有my.conf的,如果需要定制的话,可以 到/usr/local/Cellar/mysql/5.XX/support-file/目录下 拷贝一份适合的.conf文件到/etc/my.conf

mysql默认编码

mysql在mac下的默认编码是utf-8(在我机子上是), 可以使用show varibles like ‘character_set%’;来查询