Archive for category Ruby

ruby method before filters

rails 里面有alias_method_chain实现了方法的前置过滤
这里的是用alias_method实现的

class MethodFilter

  def self.before_filter(method)
    puts "add before filter here"
    method = method.to_s
    eval_string = "
      alias_method :old_#{method}, :#{method}

      def #{method}(*args)
        puts 'call'
        old_#{method}(*args)
        puts 'after'
      end
    "

    class_eval(eval_string)
  end
end

class Demo < MethodFilter

  def hello
    puts "hello"
  end

  before_filter(:hello)
end

Demo.new.hello

没有评论

rvm使用(原)

ruby version manager(RVM)

一.安装,网上常用的方法有两种
第一种方法(需要安装git)

mkdir -p ~/.rvm/src/rvm/
cd ~/.rvm/src
git clone http://github.com/wayneeseguin/rvm.git
cd rvm
./install

第二种方法

$ bash < <( curl http://rvm.beginrescueend.com/releases/rvm-install-head )

官方这两种方法都给了,还是第二种方法简单给力
使用方法,更新自己的bash session,也就是~/.bashrc(这个要看用的是哪个类型的shell,如果是zsh,那么就是zshrc)
添加一行[[ -s "$HOME/.rvm/scripts/rvm" ]] && . “$HOME/.rvm/scripts/rvm” 然后source一下.bashrc就OK了

二.使用rvm
1.装两种ruby的版本
rvm install 1.9.1
rvm install 1.8.7

安装ruby的企业版本
rvm install ree-1.8.7-2010.02

2.更换ruby版本
rvm 1.8.7 –default,就是将ruby 1.8.7换成默认的版本

3.更新ruby版本
rvm upgrade 1.9.1 如果你的1.9.1安装的是一个非release版本的ruby,那么rvm将会为你安装一个release版本

三.管理gems 和bundle

http://marcgrabanski.com/articles/gem-management-with-rvm-and-bundler

1.rvm exec

rvm 1.8.7 exec gem install rails  # 只在1.8.7下面安装rails
rvm 1.8.7 exec gem uninstall rails     # 卸载1.8.7下面的rails
rvm 1.8.7 1.9.1 gem install rails   # 两个版本下面都安装rails
rvm exec gem install rails        # 多个版本都安装rails

rvm ruby demo.rb                  # 用所有的ruby版本执行demo.rb
rvm 1.8.7 ruby demo.rb            # 用所有的ruby版本执行demo.rb

2.rvm rake

rvm 1.8.7 1.9.1 rake db:migrate   # 使用两个ruby版本运行
rvm 1.8.7 rake db:migrate         # 使用一个ruby版本运行

3.使用命名的gem版本

rvm gemset create demo            # 创建一个叫做demo的gem版本,然后使用它
rvm gemset use demo               # 使用创建的gem环境

可以看到这里下安装了哪些gems
neo@ubuntu:~/.rvm/help$ gem list
*** LOCAL GEMS ***
rake (0.8.7)

没有评论

rails关键字过滤

从前了解关键字过滤以为就是普通正则表达式的循环,原来关键词的过滤也是有算法的!!!
下面是一个简单的实现的dfa词法树,写给一个论坛板块做关键词过滤的,随着关键词的递增,耗时与正则表达式比起来要节约很多

class WordReplacement < ActiveRecord::Base

  def self.replacement_hash
    Hash[*all.collect{|re| [re.regex_str,re.replacement] }.flatten]
  end

  def self.filter_word_tree(object = nil)
    word_tree = Array.new(256)
    word_tree << 0

    object = replacement_hash if object.nil?

    object.each do |word,replace|
      temp  = word_tree
      bytes = word.bytes.to_a
      len   = bytes.size

      bytes.each_with_index do |asicc_code,arr_index|
        if arr_index < len - 1
          if temp[asicc_code].nil?
            node = [Array.new(256),0]
            temp[asicc_code] = node
          elsif temp[asicc_code] == 1
            node = [Array.new(256),1]
            temp[asicc_code] = node
          else

          end
          temp = temp[asicc_code][0]
        else
          temp[asicc_code] = 1
        end # end if
      end # end bytes
    end # end word
    [word_tree,0]

  end


  def self.handle_word(do_words,replace = true,word_tree = nil,word_hash = nil)
    word_tree = filter_word_tree if word_tree.nil?
    word_hash = replacement_hash if word_hash.nil?
    temp      = word_tree
    nodeTree  = word_tree
    words     = []
    word      = []
    to_replace= []
    a         = 0
    while a < do_words.size
      index = do_words[a]
      temp = temp[0][index]
      if temp.nil?
        temp = nodeTree
        a = a - word.size
        word = []
        to_replace = []
      elsif temp == 1 or temp[1] == 1
        word << index
        to_replace << a
        words << word
       
        if replace
          replace_word = word_hash[asicc_code_to_s(word)]
          do_words[(a-to_replace.size + 1),to_replace.size] = replace_word
          a = (a - to_replace.size + 1) + (replace_word.size - 1)
        else
          a = a - word.size + 1
        end
        word = []
        to_replace = []
        temp = nodeTree
      else
        word << index
        to_replace << a
      end
      a += 1  
    end
    return do_words if replace
    words.collect{|e| e.collect{|ch|ch.chr}.join }
  end

  protected
  def self.asicc_code_to_s(words)
    words.collect{|e| e.chr }.join
  end

end

2 Comments

ruby observer模式

ruby的观察者模式范例

require 'observer'
class User
  include Observable
  attr_accessor :username
  attr_accessor :password
 
  def initialize(username,password)
      @username = username
      @password = password
  end
 
  def change_username
        changed
        @username = "find_by_username"
        notify_observers
  end

end

class Foo
    def update()
        p "attribute has update"
    end    
end
#试着改变username属性
  user = User.new("neo","123")
  user.add_observer(Foo.new)
  user.change_username

没有评论

ruby diff工具

基于ruby_lcs简单的文件版本比较(假装支持HTML);
ruby_lcs不支持中文,需要重写String类的size方法,需要修改Diff::LCS.traverse_sequences
默认都中文会变成乱码类似”\232\234\232″,而string的[]会将它分成”\232″、”\234″、”\232

require 'jcode'
class String
  def size
    self.jsize
  end
end

class NeoDiff
  $KCODE = "u"
  attr_accessor :output
  attr_accessor :last_call
 
  def initialize(output)
    @output = output
    @last_call = nil
  end
 
  def change(event)
    if @last_call.nil?
      @output << "<span class='change'>#{event.old_element}"
    elsif @last_call == "change"
      @output << event.old_element
    else
      @output << "</span><span class='change'>#{event.old_element}"
    end
    @last_call = "change"
  end

  def match(event)
    if @last_call.nil?
      @output << "<span class='match'>#{event.old_element}"
    elsif @last_call == "match"
      @output << event.old_element
    else
      @output << "</span><span class='match'>#{event.old_element}"
    end
    @last_call = "match"
  end


  def discard_a(event)
    if @last_call.nil?
      @output << "<span class='only_a'>#{event.old_element}"
    elsif @last_call == "discard_a"
      @output << event.old_element
    else
      @output << "</span><span class='only_a'>#{event.old_element}"
    end
    @last_call = "discard_a"
  end

  def discard_b(event)
    if @last_call.nil?
      @output << "<span class='only_b'>#{event.new_element}"
    elsif @last_call == "discard_b"
      @output << event.new_element
    else
      @output << "</span><span class='only_b'>#{event.new_element}"
    end
    @last_call = "discard_b"
  end
end

没有评论