對抗垃圾信!請您點這裡:

我的E-mail:
我的Skype:My status

2008年7月3日

HTTP Response 500!?

剛剛在解決一個小Bug
用瀏覽器瀏覽某個會丟301的網站時,在Ruby或Telnet都會丟500回來
什麼鬼.. 怎麼會這樣?

其實這是因為沒有User-Agent的關係啦
有些Web Server可能會Reject一些Header中沒有User-Agent的Request
所以這時候只要在丟request時加上User-Agent這個Header即可
原本的原始碼:

response = Net::HTTP.get_response(URI.parse(uri_str))
改成:
uri = URI.parse(uri_str)
http = Net::HTTP.new(uri.host)
response = http.send_request('GET', uri.request_uri, {"User-Agent" => "Mozilla/5.0"})
這樣一來不管是301、302,還是最該死的404都沒問題啦XD

(( 因為這篇是工作上的心得,所以只好擺在Rails啦XD

2008年6月24日

修改error_messages_for,讓表單錯誤資訊中文化更完整

今天摸會了Git,就順便應用上了
error_messages_for大家都用過,也都知道這個不管再怎樣中文化,欄位名稱一樣都會出現給你看!
這真的是令人又愛(英語體系者愛)又恨(非英語體系者恨)的功能啊..
沒辦法,只好自己動手了...
我剛剛發了Git pull給Rails團隊,他們接受不接受我不知道,所以在這邊教大家如何自己搞定這一切
首先,先打開Rails這部份的原始碼
假設我Ruby安裝在C:\
所以路徑就是:C:\ruby\lib\ruby\gems\1.8\gems\actionpack-2.1.0\lib\action_view\helpers\active_record_helper.rb
接 著,跳到error_messages_for那段程式碼,在options = params.extract_options!.symbolize_keys底下加入:fields = options[:fields].nil? ? {} : options[:fields]
然後把error_messages = objects.sum {|object| object.errors.full_messages.map {|msg| content_tag(:li, msg) } }.join這行註解,改為:

error_messages = objects.sum {|object| object.errors.full_messages.map {|msg|
unless fields[msg.split(" ")[0].downcase.to_sym].nil?
msg = msg.split(" ")
field_name = msg.shift.downcase!
msg = msg.reverse.push(fields[field_name.to_sym]).reverse.join(" ")
end
content_tag(:li, msg)
} }.join
存檔離開,然後這樣用:
error_messages_for(:project, :fields => {:name => "專案名稱", :summary => "專案摘要"})
而content_tag產生出來的就會是
  • 專案名稱 can't be blank

  • 專案摘要 can't be blank

  • 很簡單吧:P?
    注意,只能夠傳小寫的symbol進去
    沒辦法,我功力太差了=_=|||
    可以參考這邊:http://github.com/cfc/rails/commit/9e38903fd10a2de9ae9c2ca53623469f3575b43c
    有任何問題歡迎提出,也可以在github上commit給我
    多謝多謝:P

    2008年4月17日

    Yahoo-LifeType-API (Yahoo!奇摩生活+ Ruby API)

    今天剛看到生活+釋出API(其實早就釋出了,API網址:http://tw.developer.yahoo.com/lifestyle_api.html)後,就開始把NetBeans打開來寫程式了XD
    現在RubyForge的專案還沒開,倒是GoogleCode的已經開了(網址:http://code.google.com/p/yahoo-lifetype-api/)
    程式是BSD授權,忘記怎樣包裝Gem檔,等到哪天想起來再包XD
    程式使用範例(列出生活+的分類):

    #!/usr/bin/env ruby
    APPID = "NhYX9XjV34FPxdq7zD8T7wwc4QGI5VWu_48NHh03zbPYUfPpcWrpZzhcVDKFQsH9dQ--"
    require 'lifetype'
    require 'rexml/document'
    include REXML

    puts "獲取生活+類別中... 請稍後"
    doc = Document.new(LifeType::Class.new(APPID).listClasses)
    puts "獲取類別結束"
    puts "類別總數: " + doc.get_elements("//rsp/ClassList")[0].attribute("count").to_s
    puts "列出類別中... 請稍後"
    doc.elements.each("//rsp/ClassList/Class") do |ele|
    puts "ID: #{ele.attributes["id"]} -- #{ele.get_elements("Title")[0].text}"
    end
    puts "列出類別結束"
    很簡單的就可以使用了,還有doc喔!
    有Bug可以丟到GoogleCode的Issues或者丟到我信箱內
    謝謝^^


    2007年9月13日

    偵測DNS是否還活著.. 用Ruby

    有鑒於某台主機的DNS常常掛掉.. 所以就寫了這個小程式..

    while true
      `ps aux | grep named`.split("\n").each{|line|
        user, pid, cpu, mem, vsz, rss, tty, stat, start, time, *command = line.split("\s")
        flag = true if command[0] == "/usr/sbin/named"
        `/etc/init.d/named start` unless flag
      }
      sleep 300
    end


    2007年9月10日

    線上Ruby Regular Expression Editor

    Ruby/Rails寫到一半.. 忽然需要用到RegExp來驗證某個東西(Ex: E-mail),卻臨時找不到工具可以測試自己寫的RegExp是否正確該怎辦?
    沒關係!這邊有個網站:http://www.rubular.com/
    這個網站可以讓您線上測試RegExp是否正確唷:)
    可以試試看!

    資料來源:China on Rails http://chinaonrails.com/topic/view/723/1.html

    2007年7月30日

    WxWidgets初體驗

    最近無聊想寫點小程式.. 可是不想用Visual Basic寫,用Ruby + GUI Toolkit寫
    可是該選哪套GUI Toolkit? 說真的.. GTK+好難用喔ˊˋ.. Qt完完全全不想用
    WindowsAPI? 那我乾脆用VB就好了=..=
    選來選去看來看去.. 乾脆就看了godfat的建議,去玩wxWidgets
    wxWidgets在Ruby上的binding叫做WxRuby,我們先來做準備吧。
    首先,我們要安裝wxWidgets跟WxRuby
    連線到http://www.wxwidgets.org/下載wxWidgets
    接著打開命令提示字元,輸入gem i wxruby -y
    一切搞定後,就可以開始先來寫個"哈囉握的"
    開啟irb,輸入以下程式碼

    require 'rubygems'
    require 'wx'
    include Wx # => 我比較懶XD

    class HelloWorld <> on_init override
    helloframe = Frame.new(nil, -1, "HelloWorld")
    StaticText.new(helloframe, -1, "Wa ha ha")
    helloframe.show
    end
    end

    HelloWorld.new.main_loop

    在wxWidgets中,每個視窗都是一個Frame,而StaticText則是Label(在VB中就叫做Label,SWT我不知道XD)
    Okok.. 可以動對不對? 不能動那就.. (( 當作沒看到

    繼續...
    或許各位會認為很奇怪,為什麼要自己慢慢寫.. 不要用視覺化的開發工具呢?
    現在來跟各位介紹,在GTK中有所謂的Glade,那在wxWidgets呢?當然有wxGlade!
    如果不喜歡wxGlade,這邊也有列表:[網址太長請點我]
    在wxWidgets中,支援一種叫做XRC(XML Resource)的格式檔案,很多視覺化工具,如wxGlade都支援輸出這種檔案。
    這種檔案的好處是不管是哪種開發工具或者程式語言,都可以藉由這個XRC檔案來產生一樣的介面。
    各位可以到http://wxglade.sourceforge.net/下載wxGlade,安裝後就可以開始拖拉了。
    弄好一個介面後,我們選擇產生XRC檔案。
    接著在同個目錄下,新增一個.rb檔案。
    假設我們有一個Frame與一個Button
    Frame: MainFrame
    Button: btnButton
    程式碼如下

    require 'rubygems'
    require 'wx'
    include Wx

    class MainFrame < btn =" find_window_by_id(xrcid('btnButton'))" xml =" XmlResource.get" xrc_file =" File.join(File.dirname(__FILE__)," main =" MainFrame.new">
    OK,大致上就這樣囉..

    2007年6月29日

    Rails中實做下拉式選單

    太久沒有寫文章了.. 最近接到一個案子.. 剛好讓我重溫Select的使用方法..
    嗯.. 結果卡在multiple,不知道是我太想睡還是怎樣.. 居然傻了..
    跑去#rubyonrails問,一位名為carpet_the_walls的網友給了我他寫的文章,網址是:
    http://shiningthrough.co.uk/Select+helper+methods+in+Ruby+on+Rails
    在此先謝謝carpet_the_walls (Thank you, carpet_the_walls)

    來做個Memo.. 不然又忘記了..
    在Rails中真的有一堆Select helper可以用.. 不只carpet_the_walls混淆,連我也模糊不清!
    常見的有三個..
    select, select_tag, collection_select(其餘的什麼select_date那些不談)
    我們先來看看一個基本的下拉式選單骨架

    <select name="selection">
      <option value="1">Opt1</option>
      <option value="2">Opt2</option>
    </select>
    在一個下拉式選單中,有一些是必備的資訊,像是"name"、"value"與"text"三個,在回傳資訊給Server時,"name"將是接收資訊用的,而"value"會傳回被選的值,而"text"則是使用者會看到的字,依上面的例子來講,Opt1、Opt2這兩個就是屬於"text"

    開始講講那三種Select helper

    select:
      select(object, method, choices, options = {}, html_options = {})
      在ActionView::Helpers::FormOptionsHelper中定義

    • object是一個實體化變數,這裡很明顯的就是要擺上model物件嘛!
    • method則是object的一個屬性,也是資料表中的對應欄位
    • choices就是要被選的選項,可以是陣列或者是雜湊(Hash)
    • options與html_options則是一些選項
    在這邊來舉個例子吧
    <%= select("project", "teacher_id", @teachers.collect{|t| [t.name, t.id]}, { :include_blank => false }) %>
    <%= select("project", "student_id", {"CFC" => '1', "EF" => '2'}) %>
    第一個例子中,@teachers在Controller是這樣的
    @teachers = Teacher.find(:all, :select => 'id, name')

    select_tag:
      select_tag(name, option_tags = nil, options = {})
      在ActionView::Helpers::FormTagHelper中定義

    如果你很喜歡手動打option的話.. 那用select_tag準沒錯啦!
    在select_tag中,name將會是params所接收值所用的鍵
    直接看範例
    <%= select_tag 'user', "<option>CFC</option>" %>
    這時在Controller中將會用params[:user]來接收傳過來的值
    但是select_tag也可以搭配options_for_select或者options_from_collection_for_select一起使用.. 來看一個範例吧
    <%= select_tag('sid[]', options_from_collection_for_select(@students, 'id', 'name'), :multiple => true)%>
    因為加上了:multiple,所以可以接受多值選擇,這時在Controller接收到的sid將會是一個陣列,這也是我所卡住的地方.. (( 真丟臉

    collection_select:
      collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
      在ActionView::Helpers::FormOptionsHelper中定義

    如果資料來源是從資料庫來的話,可以使用這個來做下拉式選單。
    這個Object不用我說,就是你的model
    method呢?當然就是欄位啦
    其實嚴格說起來,這只是select+options_from_collection_for_select的組合啦!
    範例:
    <%= collection_select(:payment, :id, @payments, :id, :name, options ={:prompt => "-Select a continent"}, :class =>"payment") %>

    再次謝謝原作者carpet_the_walls:)

    2007年6月16日

    Ruby library -- SMS

    這個Library搭配http://www.twsms.com才可以使用喔!
    有任何問題可以直接回這篇文章,或者寫信問我,我信箱是Gmail的,帳號跟我的這個部落格帳號一樣

    我先說用法好了:

    require 'twsms'
    sms = TWSMS.new(username, password) # 帳號密碼
    sms.sendSMS(mobile, message) # mobile: 目標手機號碼  message: 要傳的訊息
    原始碼:
    =begin
      == Information ==
      === Copyright: Apache 2.0
      === Author: CFC < zusocfc@gmail.com >
      === Prog. Name: TWSMS lib
      === Version: 0.1
      == Introduction ==
        TWSMS(Taiwan SMS)
        TWSMS is a SMS sender, it must use with http://www.twsms.com.
        There has no any library for the SMS system in Taiwan. So, I just coded this and release this version.
        This version just support for sending SMS.
      == Featured ==
       
      == Using TWSMS ==
        It just support for standalone class now.
        require it before you use.
      === Using TWSMS by standalone class
        require 'twsms'
        sms = TWSMS.new('username', 'password')
        sms.sendSMS('09xxxxxxxx', 'Hi, there! TWSMS library is so easy to use!')
        sms.sendSMS('09xxxxxxxx', 'Send SMS with options',
            :popup => 1,
            :type => "now",
            :mo => "Y")
    =end

    %w|uri cgi net/http|.each{|r| require r}

    class TWSMS
      def initialize(username, password)
        @uname, @upwd = username, password
        @options = {
          :type => "now", # Sending type: now, vld
          :popup => "",
          :mo => "Y".upcase,
          :vldtime => "86400",
          :modate => "",
          :dlvtime => "",
          :wapurl => "",
          :encoding => "big5"
        }
       
        @errors = {
          -1.to_s.to_sym => "Send failed",
          -2.to_s.to_sym => "Username or password is invalid",
          -3.to_s.to_sym => "Popup tag error",
          -4.to_s.to_sym => "Mo tag error",
          -5.to_s.to_sym => "Encoding tag error",
          -6.to_s.to_sym => "Mobile tag error",
          -7.to_s.to_sym => "Message tag error",
          -8.to_s.to_sym => "vldtime tag error",
          -9.to_s.to_sym => "dlvtime tag error",
          -10.to_s.to_sym => "You have no point",
          -11.to_s.to_sym => "Your account has been blocked",
          -12.to_s.to_sym => "Type tag error",
          -13.to_s.to_sym => "You can't send SMS message by dlvtime tag if you use wap push",
          -14.to_s.to_sym => "Source IP has no permission",
          -99.to_s.to_sym => "System error!! Please contact the administrator, thanks!!"
        }
        @args = []
        @url ||= "http://api.twsms.com/send_sms.php?"
        @url += "username=" + @uname
        @url += "&password=" + @upwd
      end
     
      def sendSMS(mobile, message, opt={})
        @options[:mobile], @options[:message] = mobile, message
        @options.merge!(opt).each{|k, v| @args << k.to_s + "=" + CGI::escape(v.to_s)}
        @url += "&" + @args.join("&")
        self.chk_val
        chk_errors(Net::HTTP.get(URI.parse(@url)))
      end
     
      def chk_val
        @options[:dlvtime] = "" unless @options[:type] == "dlv"
        @options[:wapurl] = "" if @options[:type] != ("push" && "upush")
      end
     
      def chk_errors(resp)
        resp = resp.split("=")[1]
        if @errors.has_key?(resp.to_s.to_sym)
          puts "==========", "Error!! Message: ", @errors[resp.to_s.to_sym]
        else
          puts "==========", "Message has been send! Your message id is: " + resp.to_s
        end
      end
     
      protected :chk_val
    end
    晚點丟到Google Code Hosting上去...

    Updated:
    TWSMS on Google Code Hosting: http://code.google.com/p/twsms/
    SMSender on RubyForge: http://rubyforge.org/projects/smsender/

    2007年6月12日

    find_by_randomize -- 讓ActiveRecord可以亂數取資料

    請在model內加入:

    def self.find_by_randomize
      ids = self.find(:all, :select => [id])
      self.find(ids[rand(ids.size)]["id"].to_i)
    end
    這樣一來,就可以取亂數選取資料了!

    請參考這篇:為你的 Active Record 做出多采多姿的 find

    當然囉.. thegiive那個就是我修改的範本:P

    2007年5月15日

    具有破壞版面功用的HTML標籤:plaintext

    剛剛寫程式寫到一半忽然想到這個破壞力極大的標籤
    雖然這個標籤不會造成多大的危害,但是在某些網站上,還是可以造成一定程度的破壞
    所以請各位Web Developers注意,過濾掉這個標籤:<plaintext>
    另外,HTML的註解標籤也請過濾,也就是:<!--
    這兩個都可以破壞版面!
    結果請看這邊:
    http://willh.org/cfc/cfc_priv/plaintext.htm

    解決方式:
    如果是使用黑名單來擋HTML標籤,請把plaintext給加入
    如果沒有使用檔標籤的套件,請盡快使用
    如果沒有辦法使用檔標籤的套件,請透過Regular Expression幹掉它!

    2007年5月13日

    php+ruby(with ActiveRecord)又一新範例 -- RSS聯撥器

    上個例子,我們用PHP + Ruby 搭配ActiveRecord的方式來寫資料新增的程式
    今天我們就來延伸應用一下,要做什麼呢? RSS聯撥器!
    有鑒於GoogleReader的RSS聯撥器產生出來的東西太醜(只能修改一兩個小地方.. 我總覺得那好胖=  =),乾脆自己寫個來用
    Demo網址改天再PO上來,我們先來寫程式比較重要:P
    主機請記得先裝好Ruby、PHP、Apache跟MySQL;OS要啥都沒差,我比較建議LAMP的配置XD
    我們來建立一個叫做feeds的目錄包含一個子目錄,叫做lib:

      mkdir -p feeds/lib
     
    先跳到feeds/lib新增幾個會被require的檔案:

      cd feeds/lib
      touch connect.rb model.rb require.rb

    以下是各個檔案的用處:
    - connect.rb
      資料庫連線初始化
    - model.rb
      資料表模型宣告
    - rqeuire.rb
      會用到的額外library引入

    原始碼:

      - connect.rb
        #!/usr/bin/env ruby;require 'lib/require';ActiveRecord::Base.establish_connection({:adapter => "mysql",:host => "localhost",:username => "username",:password => "password",:database => "others"})
      - model.rb
        #!/usr/bin/env ruby;require 'lib/connect';class Feed < ActiveRecord::Base;end
      - require.rb
        #!/usr/bin/env ruby;%w|rubygems active_record hpricot open-uri|.each{|lib| require lib}

    一切搞定後,我們可以開始來建立資料庫了!

      mysql> create database others;
      mysql> use others;
      mysql> create table feeds(id int, uri varchar(255));
      mysql> describe feeds;
     
    看看資料表結構是否正確!
    接著回到上一層目錄,新增底下的幾個檔案:

      touch index.php list.rb new.htm new_record.rb save.php

    - index.php
      網站首頁,會列出目前的RSS feed
    - save.php
      儲存RSS feed網址
    - list.rb
      處理RSS feed
    - new_record.rb
      將RSS feed網址存入資料庫(也可以直接用php寫.. 我是沒有意見)
    - new.htm
      新增RSS feed網址的表單

    原始碼我就直接貼了

      - index.php
        <html>
          <head>
            <title></title>
          </head>
          <body>
            <a href="new.htm">Create</a>
            <ul>
        <?php
          exec("ruby list.rb", $args);
          for($i=0;$i<count($args);$i+=3)
            echo "<li><a href=\"" . $args[$i+1] . "\" title=\"作者:" . $args[$i+2] . "\">" . $args[$i] . "</a> -- " . $args[$i+2] . "</li>";
        ?>
            </ul>
          </body>
        </html>

      - save.php
        <?php
          exec("ruby new_record.rb " . $_POST["feed_uri"], $arg);
          if ($arg) echo "<script>location.href=\"index.php\";</script>";
        ?>
     
      - list.rb
        #!/usr/bin/env ruby
        =begin
            Filename: list.rb
        =end
        require 'lib/model'

        Feed.find(:all).each{|feed|
            doc = Hpricot(open(feed.uri))
            rss = doc.search("entry")
            max = rss.size > 3 ? 3 : rss.size
            max.times {|i|
              break if rss.nil?
              puts rss[i].search("title").text.gsub(/\n/, " ") # Return the title of the article to the PHP file.
              puts rss[i].search("link[@rel='alternate']")[0]["href"].gsub(/\n/, " ") # Return the link of the article to the PHP file.
              puts rss[i].search("author/name").text.gsub(/\n/, " ") # Return the author of the article to the PHP file.
            }
        }

      - new_record.rb
        #!/usr/bin/env ruby
        =begin
          Filename: new_record.rb
        =end
        require 'lib/model';puts Feed.new({:uri => ARGV[0]}).save
     
      - new.htm
        <html>
          <head>
            <title></title>
          </head>
          <body>
            <form action="save.php" method="post">
              <p>Please input the feed url:<input type="text" name="feed_uri" /></p>
              <p><input type="submit" value="Save!" /></p>
            </form>
         </body>
        </html>
     
    OK,這樣就可以啦XD

    2007年5月9日

    PHP + Ruby with ActiveRecord 範例

    如果老闆要求使用php,可是您卻是Ruby狂熱者,這.. 怎辦呢?
    沒關係! 一樣用Ruby寫,php只要做一點點的處理就好!
    How to? php中有這個函式:exec
    ( 本範例實作於Windows XP Professional搭配InstantRails;在其他作業系統上沒有測試過,不過各位還是可以嘗試看看 )
    我們來試試看吧!
    先寫個test.rb:

      #!/usr/bin/env ruby
      #
      # Filename: test.rb
      #
      puts "Hello"
      puts "world"
     
    再寫個test.php:

      <?php
        exec("test.rb", $args);
        foreach($arg as $args)
          echo $arg . "<br />";
      ?>

    將兩個檔案放在同一個目錄下後,打開瀏覽器瀏覽test.php;看!是不是顯示結果出來了?
    OK,我們直接來用ActiveRecord幫我們新增資料吧!
    我們需要一張普通頁面、一張php網頁跟一個ruby檔案:

      #!/usr/bin/env ruby
      #
      # Filename: ar.rb
      #
      require 'rubygems'
      gem 'activerecord'
      ActiveRecord::Base.establish_connection(
        :adapter => 'mysql',
        :host => 'localhost',
        :username => 'root',
        :password => '',
        :database => 'cal'
      )
     
      class Event < ActiveRecord::Base;end
     
      name, descr = ARGV[0], ARGV[1]
      puts Event.new({:name => name, :descr => descr, :date => Date.today, :time => Time.now}).save

    好了,接下來是普通頁面,這是送出表單:
     
      <!-- Filename: ar_form.html -->
      <html>
        <head>
          <title>PHP with Ruby and ActiveRecord</title>
        </head>
        <body>
          <form action="ar_save.php" method="POST">
            Username: <input type="text" name="usrname" /><br />
            Description: <textarea name="descr"></textarea><br />
            <input type="submit" value="Save it!" />
          </form>
        </body>
      </html>
     
    這是php網頁:

      <?php
        // Filename: ar_save.php
        exec("2.rb " . $_POST["usrname"] . " " . $_POST["descr"], $arg);
        if($arg[0]) echo "Success!";
      ?>

    OK,讓我們來試試看吧!
    Look!! It works!!
    現在,我們來寫個ar_read.rb跟ar_read.php來讀取資料吧:

      # Filename: ar_read.rb
      require 'rubygems'
      gem 'activerecord'
      ActiveRecord::Base.establish_connection(
        :adapter  => "mysql",
        :host     => "localhost",
        :username => "root",
        :password => "",
        :database => "cal"
      )
      class Event < ActiveRecord::Base;end
      events = Event.find(:all, :conditions => "name = '#{ARGV[0]}'")
      events.each{ |event|
        puts event.name
        puts event.descr
        puts event.date.to_s(:db)
        puts event.time.strftime("%H:%M:%S")
      } 

      <?php
        // Filename: ar_read.php
        exec("ar_read.rb " . $_GET["name"], $args);
        $info = array();
        for($i=0, $j=0;$i<count($args);$i+=4, $j++){
          $info[$j]["name"] = $args[$i];
          $info[$j]["descr"] = $args[$i+1];
          $info[$j]["date"] = $args[$i+2];
          $info[$j]["time"] = $args[$i+3];
        }
        for($j=0;$j<count($info);$j++)
          echo "Name => " . $info[$j]["name"] . "<br />Description => " . $info[$j]["descr"] . "<br />Date => " . $info[$j]["date"] . "<br />Time => " . $info[$j]["time"] . "<br />";
      ?>
     
    看看結果,hmmm.. 看起來真棒!
    嗯?如何?Ruby + ActiveRecord的威力很強大吧?
    為什麼不要直接用PHP寫就好? 因為光寫SQL你就想跳樓,何必呢?
    記住,在Ruby的檔案中,不可以用:

      puts 1, 2, 3

    這種方法,會造成php收不到回傳,因此必須用這種寫法:

      puts 1
      puts 2
      puts 3

    或者就是:

      puts 1; puts 2; puts 3

    端看個人喜好囉!

    2007年4月30日

    Array.longest ( Array.which_long?修改版 )

    感謝在Ruby-talk上的:

    Chris Carter
    David A. Black
    Harry
    Robert Dober
    James Edward
    :)
    原本的程式碼太長,而且使用內建的功能組合起來就好
    再者,原本的程式會把陣列的元素強制轉型為String

    新的程式碼為:
    class Array
      def longest
        # Harry <http://www.kakueki.com/ruby/list.html>
        self.select{|r| r.to_s.size == self.max{|x, y| x.to_s.size <=> y.to_s.size}.to_s.size}
      end
    end
    這個程式是由Harry所寫出的,底下轉貼原文:

    On 4/29/07, Billy Hsu <ruby.maillist@gmail.com> wrote:
    > Thanks for your reply, I learned more on this thread :P
    > But I have a question:
    > If I have an array contain:
    >   ary = [1, 12, 234, "456"]
    > there has two elements which size is 3, but the longest method just returned
    > one of them.
    > I can't solve it :(
    >

    Is this what you are looking for?
    Do you want all longest elements?

    big = [1, 12, 234,45,978, "456"].max {|x,y| x.to_s.size <=> y.to_s.size}
    p [1, 12, 234,45,978, "456"].select {|r| r.to_s.size == big.to_s.size}
    由於Harry不喜歡被張貼信箱,因此我將他的網站給貼上來:
    http://www.kakueki.com/ruby/list.html
    A Look into Japanese Ruby List in English

    再一次謝謝Harry的幫助:)
    也謝謝其他人,讓我學到許多東西:D
    Thanks again and again!!

    CFC --


    2007年4月28日

    Array.which_long? -- 剛出爐的函式

    class Array
    def which_long?
    # Version 1.0
    # Coded by CFC <>
    # PLEASE DO NOT REMOVE THE COMMENT OF THIS FUNCTION, THANKS A LOT.
    # Usage:
    # ['a', 'ab', 'abc' 1234].which_long?
    # => 1234
    self.size.times{|i| self[i]=self[i].to_s}
    max, long = 0, String.new
    self.each{|item| item.size > max ? (max = item.size; long = item) : next}
    long
    end
    end


    以上是原始碼,使用方式如下:

    puts ['a', 'ab', 'abc', 1234].which_long?
    => 1234

    授權還沒定,不過大家還是可以拿去使用:P
    請不要拿掉註解.. 謝謝

    2007年4月24日

    rubygems 0.9.2的問題

    本文同步發佈至:http://blog.pixnet.net/zusocfc/post/4160285


    升級Rubygems到0.9.2時,不論是安裝gem包還是升級gem包
    都會產生一個Error:

    ERROR:  While executing gem ... (NoMethodError)
        undefined method `refresh' for #<Hash:0xb799a478>

    這個時候該怎麼辦呢?
    根據這篇文章所寫:http://www.cnzxh.net/blog/Index.php?do=readArticle&articleId=145
    我們可以做這個動作:

    rm -f /usr/local/lib/ruby/gems/1.8/source_cache

    經過測試後.. 真的就正常了..
    所以如果你有出同樣問題 請照做吧:P
    ( 我想這問題只會發生在*nix系統上 )

    2007年4月20日

    大量帳號建置器 版本1跟版本2

    先說好,跟往常一樣.. 到我Pixnet的網誌看會比較不頭痛:P
    版本1可以不用寫群組名稱,但是程式碼好醜ˊˋ
    版本2必須要有群組名稱,適用於學校(?)

    版本1下載
    版本2下載

    版本1:

    #!/usr/bin/env ruby
    File.open(ARGV[0]) do |file|
      while a = file.gets
        a = a.chomp.split(/ /)
        print "username => #{a[0]} ", "password => #{a[1]} ", "group => #{a[2]}", "\n"
        a[2].nil? ? `useradd -m #{a[0]}` : `useradd -m -G #{a[2]} #{a[0]}`
        `echo #{a[0]}:#{a[1]} | chpasswd`
      end
    end
    exec "pwconv"

    使用者清單寫法:

      帳號 密碼 群組

    版本2:

    #!/usr/bin/env ruby
    require 'yaml'
    YAML.load_file(ARGV[0]).each{ |grp|
      grp.each{ |usr|
        usr.each{ |i|
          info = i.chomp.split(/ /)
          `useradd -m -G #{grp[0]} #{info[0]}`
          `echo #{info[0]}:#{info[1]} | chpasswd`
        }
      }
    }
    `pwconv`

    使用者清單寫法:

    grp1:
      - usr1 pwd1
      - usr2 pwd2
    grp2:
      - usr3 pwd3
      - usr4 pwd4
    grp3:
      - usr5 pwd5
      - usr6 pwd6
    使用方式都是:
    ./account list

    程式授權.. 隨便啦

    2007年3月26日

    HAML

    最近開始接觸HAML
    在Rails中,預設使用ERb來當作模板描述語言,可是這樣寫個人認為非常醜也非常累...
    而之前看到HAML時感覺到那東西似乎沒有太大的可用性,難道要Designer也學Ruby嗎?
    不過後來我想通了..

    架構這部分可以給Coder作,Designer乖乖設計CSS就夠了..
    來看看底下這個Sample吧:

    這是rhtml

    原始碼請看這地方:http://blog.pixnet.net/zusocfc/post/3520168

    這是HAML

    #content
    .left.column
    %h2 Welcome to our site!
    %p= print_information
    .right.column= render :partial => "sidebar"

    看!少了多少行?
    可以讓開發速度變快耶= v =...
    最主要的是,看起來也比較美觀了!

    參考:
    http://haml.hamptoncatlin.com/tutorial/
    http://haml.hamptoncatlin.com/docs/




    2007年3月11日

    Rails 安全性漏洞一則 -- attr_protected 與 attr_accessible

    我沒辦法在這邊正常的發布有表單HTML tag的文章,請連結至:
    http://blog.pixnet.net/zusocfc/post/3220943
    觀看完整文章!

    Rails中有個安全性漏洞,請參考

    * http://manuals.rubyonrails.com/read/chapter/47
    * http://www.javaeye.com/topic/58686

    假設我們有個users table,表格欄位如下:

    * username # 很明顯就是帳號
    * password # 這就是密碼
    * role # 權限名稱

    而我們提供給使用者註冊的頁面只會有username跟password欄位
    然後你的後端如果是這樣:

    User.create(params[:user])

    哦.. 這就真的好玩了..
    使用者在註冊時直接提權..
    那這要怎樣處理呢?

    我們可以在
    app/model/user.rb
    內新增這行:

    attr_protected :role

    這樣一來,該欄位就會確定被忽略掉而不會被新增..
    不過你得做一下這道手續:

    user = User.new(params[:user])
    user.role = sanitize_properly(params[:user][:role])

    ===== 分 - 隔 - 線 =====

    另外,我們可以使用

    attr_accessible :username, :password

    這有點類似白名單的方式,可以過濾掉沒出現的欄位...


    2007年3月4日

    Rails -- InPlaceEdit

    用過Flickr嗎?
    如果你有Flickr相簿,應該對於修改照片標題、說明的方式記憶猶新吧?
    那種就叫做 In Place Editing
    在Rails中,要實做這種技術並不難,因為本身就內建這個功能
    不過到了Rails 2.0將會把這個從內建移除變成Plugins形勢存在
    可以參考這篇:In-plcae-editing by Rails
    不過我在這裡重新說明一次使用方式吧
    如果有<%= javascript_include_tag :defaults %>的話,那只剩下兩個步驟:
    Controller:

    class ObjectController < ApplicationController
    in_place_edit_for :object, :method
    end


    View:

    <%= in_place_editor_field :object, :method %>

    這樣就可以建立起最基本的InPlaceEditing欄位
    可是最基本的都是英文,因此Rails也提供了修改參數,可以參考這篇
    in_place_editor_field欄位有四個參數:
    in_place_editor_field(object, method, tag_options = {}, in_place_editor_options = {})
    而修改的部分則是放在第四個參數;假設我要修改:saving_text:
    <%= in_place_editor_field(:object, :method, {}, {:saving_text => "儲存中..."} %>
    改好後記得重新整理頁面!

    另外,如果要建立多個欄位的話,必須用這種方法:
    class ObjectController < ApplicationController
    in_place_edit_for :object, :method1
    in_place_edit_for :object, :method2
    in_place_edit_for :object, :method3
    end


    這樣寫超麻煩的!因此可以這樣:

    class ObjectController < ApplicationController
    %w"method1 method2 method3".each do |m|
    in_place_edit_for :object, m.to_sym
    end
    end

    這樣未來在新增刪除上都會很方便!

    Ruby/GTK 中文教學

    這是http://www.ruby-lang.org/zh_TW/ 站長所寫的一篇教學
    網址是:http://info.sayya.org/~sjh/sjh_rubygtk.pdf
    寫得很詳細、簡單明瞭!
    如果有需要可以看看