跳到主要內容

發表文章

目前顯示的是 2014的文章

linux, bash, find 的應用(-exec, sed -i, 檔案內取代, 與xargs比較)

find -exec find -exec 指的是將找到的檔案,送到後面的指令去處理。從 -exec 到 \; 為止,代表是接受從find送來要處理的指令,而送來的檔案將用 {} 代表找到的檔案。 譬如你想把所有副檔名為 .log 的檔案刪除掉,可以這麼做 find . -type f -name "*.log" -exec rm {} \; (其實我加上 -type f 有點多餘,因為我已經指定 -name "*.log" 了,就不可能輸出資料夾了。) 如果刪檔案的時候,一直要你按 yes ,可以這樣 yes | find . -type f -name "*.log" -exec rm {} \; yes 這個指令會一直串流輸出yes,這樣刪檔案就自動一直輸入yes 例子中 find 找到的檔案,就放到 -exec 至 \; 之間的指令去處理,譬如找到了檔案 develop.log ,就會變成 rm develop.log 另外, {} 並不是規定只能出現一次,譬如你要將資料夾內所有檔案加上副檔名 log ,可以這麼做 find . -type f -exec mv {} {}.log \; 這指令會包含子資料前內的檔案都加上.log副檔名。如果只想要目前資料夾的檔案,所以可以加上 -maxdepth 1 ,若要地回到下一層資料夾可以將1改成2,3或4以此類推 find . -maxdepth 1 -type f -exec mv {} {}.log \; 因此,若要批次改變檔案的內容,就可以搭配 find -exec 跟 sed -i 。sed 加上 -i 參數,代表直接對檔案內容做修改。 我常常在幫別人複製或移動網站,很多人的網址都寫成包含域名的絕對路徑,所以常常要用這個指令去找出所有含舊域名的檔案,並改成新域名。 譬如舊域名為 http://www.old.com ,要改成 http://www.new.com ,我會這麼做 find . -type f -exec sed -i 's/www.old.com/www.new.com/g' {} \; (sed這個指令在OS X上面如果照上例那樣執行,會有...

HTML, CSS, 相對視窗或螢幕的高度與寬度

在 w3school.com 網站, CSS Units 有各種與寬度的表示法 以我使用的頻率來排序: px: 使用螢幕幾個像素(但是還要考慮Retina螢幕像素是一般螢幕像素的兩倍) %: 相對父層的大小比例 vh, vw: 相對於瀏覽器展示網頁區域的大小(不是整個瀏覽器的大小,沒包含瀏覽器的工具列,只有展示網頁的區域) vmin: vh, vw取最小值(另外還有vmax則是取最大值,但是目前IE跟safari不支援) px 與 % 很常用, vh , vw 與 vmin 是CSS3的新產物,表示相對瀏覽器展示頁面的大小 相對視窗大小 這邊先說明, vh , vw 與 vmin 只包含網頁顯示區域的長寬,不包含瀏覽器的工具列 先從dom的最根本講起好了,一份HTML文件,根是 <html></html> (雖然沒有嚴格規定,不寫也能顯示),然後這個根的父元件就是瀏覽器的網頁頁面顯示區 因此,如果對 <html></html> 宣告大小是 100% 就跟宣告 100vh 一樣,因為都是指瀏覽器的網頁頁面顯示區大小 這個範例是將html設定為100vh <html style="height: 100vh"> <head> <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script> <script type="text/javascript"> console.log($('html').height()); </script> </head> </html> 這個範例是將html設定為100% <html style="height: 100%"> <head> <script src="https://code.jquery.com/jque...

Linux, bash, 壓縮, tar, bz2, xz, 7z, 壓縮率

Linux, bash, 壓縮, tar, bz2, xz, 7z, 壓縮率 如果只是想查各種副檔名的解壓縮指令,只要Google副檔名就可以找到(例如: tar.bz2 ) 這邊主要是在對資料夾壓縮時,為了自訂壓縮率而深入研究壓縮指令而產生。 tar 可以對檔案或資料夾進行單存的打包(或解開打包),後面接c代表打包,x代表解開打包。這邊在Bash底下產生一個簡單的文字檔來練習: echo "Hello World" > text tar c text # 輸出 text000644 000765 000000 00000000014 12437746653 012241 0ustar00wemeewheel000000 000000 Hello World # 如果要儲存,加上參數f,並指定存檔名稱 tar cf text1.tar text # 或者使用串流來寫入檔案也可以(實際應用不建議) tar c text > text2.tar 原始檔案12B, 打包後2K, 使用串流寫入的10K, 可以確定打包完全不會有壓縮的效果 12B 12 4 10:57 text 2.0K 12 4 11:01 text1.tar 10K 12 4 11:01 text2.tar 其實打包主要目的在於,我常用的bz2壓縮,只能對檔案壓縮,不能對目錄壓縮,所以才需要先把目錄打包成一個檔案,再用bz2去壓縮它 接下來,弄個目錄跟文字檔來測試 mkdir dir echo "Hello World" > dir/text tar cf dir1.tar dir tar c dir > dir2.tar 結果一樣,使用串流寫入的,佔的容量比較大 102B 12 4 11:28 dir 2.5K 12 4 11:44 dir1.tar 10K 12 4 11:44 dir2.tar 接下來,使用bz2壓縮看看 bzip2 -z dir1.tar bzip2 -z dir2.tar 來看看所佔用的容量 102B 12 4 11:28 dir 167B 12 4 11:44 dir1.tar.bz2 169B 12 4 11:44 dir2...

Ruby, dup跟clone的不同, 淺層複製與深層複製

Ruby, dup跟clone的不同, 淺層複製與深層複製 Ruby裡面,對於物件的複製有兩個方法,分別是對物件呼叫 dup 跟 clone ,這兩種有什麼不同呢?這兩種方法並非只是alias的名稱而已。 先不討論 淺層複製 跟 深層複製 的問題,先來看看呼叫dup做了什麼事情。假設有個class: class Foo def foo 'foo' end end 我們來試試看,產生Foo物件,然後對他呼叫 dup : foo = Foo.new dup_foo = foo.dup dup_foo.foo # => 'foo' 一切依照預期,順利的進行複製了,接下來我們對foo動態增加一些Method上去,看看能不能夠複製(至於如何對物件動態增加Method請參考 這篇 ) class << foo def run 'run' end end foo.foo # => 'foo' 原本class就有宣告 沒問題 foo.run # => 'run' 動態新增的Method 也沒問題 dup_foo_2 = foo.dup dup_foo_2.foo # => 'foo' 原本class就有宣告 沒問題 dup_foo_2.run # => 發生錯誤,No Method Error 由此,可以知道,dup方法,僅對完整宣告的class進行複製,動態增加的不會複製,那麼我們再多測試一點,使用另一種方法增加Method。我們把整個程式碼完整再寫過 class Foo def foo 'foo' end end foo = Foo.new dup_foo = foo.dup # 使用另一種方法增加Method到Foo上面去 class Foo def go 'go' end end foo.go # => 'go' dup_foo.go # => 'go', 正常執行 由此可見,只要是宣告...

RUBY,大寫數字轉小寫數字,國字數字轉阿拉伯數字

RUBY,大寫數字轉小寫數字,國字數字轉阿拉伯數字 今天,我在處理中文地址的時候,發現有人的門牌號碼填國字,譬如 中正路四三號 ,也有人會填 中正路43號 ,當然沒人是填 中正路肆參號 ,反正程式邏輯是一樣的。(本方法忽略 四十三 -> 43 這種格式,若有必要,請自行寫程式判定 京兆億萬千百十 出現的位置,是否合理,然後再進行轉換) 一般想到的就是把字串裡面每個字遍尋一遍,然後寫個switch,對出現的字元進行轉換,譬如: // psudo code for each character in string switch(character) case: '一' convert_to(1) case: '二' convert_to(2) . . . case: '九' convert_to(9) end end 但其實你使用的是Ruby語言的話,其實Ruby語言有提供一個很簡潔的方法 string.tr(from_str, to_str) 使用的方式是這樣子的,提供兩個字串,兩個字串相對應的位置會互相轉換,譬如提供兩個字串: #輸入字串1 'abc' #輸入字串2 '123' 則會將a變為1, b變為2, c變為3,舉個實際例子: "xx_abc_xx".tr('abc', '123') # 輸出 "xx_123_xx" "xx_ccc_xx".tr('abc', '123') # 輸出 "xx_333_xx", '1'跟'2'都沒出現?因為呼叫tr的字串裡面也沒有'a'跟'b'呀~ "cba".tr('abc', '123') # 輸出 "321", 為什麼反過來?因為呼叫tr的字串是'cba'呀~(a變為1, b變為...

Ruby: class << self

Ruby: class << self 我們先不管class << self是什麼意思,我們先來看看動態語言有哪些有趣的用法。 Ruby可以動態的在class裡面新增,修改一些方法。譬如: class Foo def foo return 'Hello Foo' end end f = Foo.new puts f.foo # Hello Foo class Foo def foo return 'Edit Foo' end end puts f.foo # Edit Foo 有玩過RPG Maker的人應該很熟練了,RPG Maker的模組都是這樣掛上去的,直接把模組複製到整個Script的最後面,將系統原先的方法override掉(這邊我講override其實有點問題,因為override比較適合用在編譯時期,子類別繼承並修改父類別的方法,但這裡單純只是修改類別原先的方法) 好的,那如果我產生兩個Foo物件,延續上例的類別 class Foo def foo return 'Hello Foo' end end f1 = Foo.new f2 = Foo.new puts f1.foo # Hello Foo puts f2.foo # Hello Foo class Foo def foo return 'Edit Foo' end end puts f1.foo # Edit Foo puts f2.foo # Edit Foo 因為是直接對類別做修改,所以上例中,f1與f2的行為都會改變。 那如果我們今天想要做出像Javascript那種功能,只對單一物件新增或修改方法,有辦法做到嗎?譬如Javascript可以這麼做: function Foo(){ } Foo.prototype.foo = function(){ return "Hello foo"; } var f1 = new Foo(); var f2 = new Foo(); console.log( f1.foo() ); // Hello foo console....

Ruby: module, include, extend, self, module_function

module 一個最簡單的module include 在class使用include, 可以讓module內的方法為class的物件方法,在ruby稱為mixin include可用在模擬多重繼承,因Ruby不像C++可以直接多重繼承,所以宣告為module,在mixin到class裡面 extend 在class使用extend,可以讓module內的方法為class的類別方法 與include的不同點在於 include: module內的方法為class的物件方法 extend: module內的方法為class的類別方法 module Foo def foo puts 'foo' end end class Bar extend Foo end Bar.foo # 印出hello foo (foo已成為Bar的類別法) self in module self是什麼?就是呼叫Ruby當前物件本身指標所指的,在主程序直接呼叫self返回main。 先看最簡單的module module Foo end 直接呼叫self會出現什麼呢? module Foo p self #印出 Foo end 別忘了ruby式腳本式的語言,這個程式沒寫錯,單純只是宣告module,他裡頭的命令句還是被執行,所以印出Foo 那麼這個Foo物件是什麼?簡單,印出來看看 module Foo p self.class #印出Module end 非常清楚,Ruby號稱所有東西都是物件,所以module也是物件,所以self的使用很清楚了,直接動態的在Foo物件上面加上方法 module Foo def self.foo puts 'hello foo' end end Foo.foo # 印出hello foo, 直接呼叫Foo這個Module形態的物件,裡頭的foo方法 所以同理,class裡面的self也是一樣的應用,class也是可以實體化為物件,並動態的加上方法,通常稱為類別方法,這種類別方法,在其他程式語言裡面也很常用,只是實作方式不同,Ruby是把class也當作物件處理 extend self 綜合上面所說的,如果m...

twitter-bootstrap-rails使用font awesome

twitter-bootstrap-rails 已經把 font awesome 編譯在裡面了,不過用法有點不一樣,我是上stack over flow才知道, ,這種更動沒有寫在README裡面誰知道啊 這邊是 標準font awesome 的用法 譬如 <i class="fa fa-anchor"></i> 不過用twitter-bootstrap-rails編譯在裡頭的font awesome要這樣用 <i class="icon-anchor"></i> 第一個fa不用,第二個fa改成icon 或者直接使用它的Helper <%= glyph(:anchor) %> 用Helper是比較簡潔一點

ssh 直接複製到檔案結尾 (ssh append to file)

scp 沒辦法,scp會直接覆蓋。rsync沒辦法,會讓兩個檔案同步變成一模一樣... 這時候就只好用ssh 原始操作方式 ssh user@remote "要處理的指令" 那麼就簡單了,如果要抓取遠端的檔案,附加到本地,那就在遠端使用 cat 指令,然後用 >> 修改資料串流附加到本地的檔案不就行了嗎?沒錯 ssh user@remote "cat filename" >> /LocalPath/FileName 那我就舉一反三,資料串流改用 > 就是複製!!! ... 對不起,脫褲子放屁了,直接用 scp 或 rsync 不就好了... 這邊就是發現 scp 或 rsync 只能複製,我們才去找可以附加檔案的方式,別又把這個方法,重新拿回去當複製的的功能用,有句名言 當你手上拿著鎚子,你就覺得任何東西都像釘子 好,剛剛是抓遠端檔案附加到本地,那反過來,抓本地檔案附加到遠端呢?我上查到了一個很神奇的用法 cat local-source-file-name | ssh user@some.domain “cat >> remote-target-file-name“ 得改用管線的指令,如果用 ssh user@some.domain “cat >> remote-target-file-name“ < cat local-source-file-name ,一定失敗,因為那串指令會通通送到遠端去執行, cat local-source-file-name 這個指令也是在遠端執行,根本不是 cat 你本地的資料。 總結: 遠端到本地,直接ssh 遠端 cat 檔案 >> 本地檔案 本地到遠端,要做管線,cat 本地檔案 | ssh 遠端 cat >> 檔案

安裝zsh + oh-my-zsh 出現 /usr/bin/env: zsh: 沒有此一檔案或目錄 (/usr/bin/env: zsh -: No such file or directory)

zsh 跟 oh-my-zsh 安裝完,可能會出現類似下面錯誤訊息,雖然他沒任何影響,不過我總覺得怪怪的 # 中文系統 /usr/bin/env: zsh: 沒有此一檔案或目錄 # 英文系統 /usr/bin/env: zsh -: No such file or directory 通常會出現這類的訊息,都是指令找不到。 這邊指zsh這個指令找不到,試試看輸入 which zsh 看看是不是沒有把zsh這個加到 $PATH 裡面,沒有的話加入就好了。 如果加入了一樣找不到,我trace了一下zsh的執行過程,通常都是跟 oh-my-zsh 的安裝順序錯了的時候才會發生。 這時編輯家目錄底下檔案 vim ~/.zshrc ,會看到 # 他先執行了oh-my-zsh.sh source $ZSH/oh-my-zsh.sh # 然而oh-my-zsh.sh已經在使用zsh這個指令了 # 這裡才把宣告路徑,所以當然zsh指令找不到 export PATH="/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/bin:/bin:/root/bin:/usr/local/bin" 這時就把它們兩個對調一下就好了 # 像這樣把 export PATH 放到 source $ZSH/oh-my-zsh.sh 上面 export PATH="/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/bin:/bin:/root/bin:/usr/local/bin" source $ZSH/oh-my-zsh.sh # 這樣oh-my-zsh.sh裡面就可以用zsh指令了 存檔後,登出再進來,他就可以正常使用zsh指令,不再出現這種錯誤訊息了

CentOS zsh 自行編譯

CentOS用yum安裝的zsh版本有點舊,這邊記錄一下,怎麼下載自己安裝 # 下載最新版的 zsh (筆下日期 2014/03/11) 並存檔為 zsh.tar.bz2 wget http://sourceforge.net/projects/zsh/files/latest/download\?source\=files -O zsh.tar.bz2 # 解壓縮 tar xvjf zsh.tar.bz2 # 你的版本不一定是5.0.5,我筆下日期 2014/03/11 到5.0.5版,你的可能更新 cd zsh-5.0.5 # 普通編譯流程,configure後 看缺什麼lib 裝一裝 ./configure make sudo make install # 把"/usr/local/bin/zsh" 這串字加到 sudo tee -a /etc/shells 裡 echo "/usr/local/bin/zsh" | sudo tee -a /etc/shells # 上面那一步 你的 chsh -l 才查得到zsh # 可以切換到/usr/local/bin/zsh 了 chsh -s /usr/local/bin/zsh # 重新登入 shell就切換過去了 exit # and relogin # 跟bash一樣,放個.zshrc檔案在使用者根目錄,讓系統進入zsh前讀取 touch ~/.zshrc # 你的變數 或alias就可以加在這裡面了 # 有點跟bash不一樣的地方是,沒有.zsh_profile,讓系統只讀第一次的檔案 # 如果你有裝oh-my-zsh,建議直接建立軟連結(上面那一步touch就不用做了,做了就先把~/.zshrc刪掉就可以了) ln -s ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc

Linux系統which與type指令,對比$PATH與Hashed路徑

我安裝Ruby後,為了搞定路徑花了老半天,後來弄懂了Linux指令在 which , type , $PATH 與 Hashed 就清楚多了。 如果你的系統有內建Ruby,打 which ruby ,會發現他的路徑在 usr/bin/ruby 底下,接著不管你用了什麼方法裝了新的Ruby,就把新的路徑在$PATH裡加到 usr/bin 的前面,系統通常就預設執行在$PATH裡面,放在前面先找到的那個Ruby。 但是有個情況,你加了$PATH以後沒有用,系統還是一直去執行舊的Ruby。可是打 which ruby 明明就是新的路徑呀? 我遇到的情況是這樣打 type ruby 會發現 ruby is hased(/usr/bin/ruby) ,這是什麼意思呢?為什麼 which ruby 跟 type ruby 的路徑會不一樣。這種情況是 ruby 這個命令,在系統一開始就被寫在系統的hash table裡面。這邊簡單分類一下 which 跟 type 的不同: which: 單純從$PATH裡面尋找到的路徑。 type: 指令真實被執行時使用的路徑。 which 只是單純顯示在$PATH, type 才是真實下命令按Enter後去執行的路徑。 所以安裝了新Ruby,可是系統若之前就把Ruby放在hash table裡面,他就會一直執行舊版本的Ruby,這時候只要重登目前這個Shell,讓hash table refresh一下就好了。如果還是不行,系統不曉得寫在什麼地方,他就是喜歡自動把舊Ruby放到hash table裡面。那就只好手動改了,在bash底下執行: hash -r #清掉hash table裡所有的資料 上面這樣子是全清掉,全部的hash table重新建立。或者也可以像下面這樣: hash -d ruby #單純在hash table清掉Ruby 這樣子hash table裡面沒有 ruby 了,系統就得乖乖執行$PATH裡面找到的 ruby 囉。 不只有ruby唷,不管安裝什麼 php , python 還是 sqlite 之類的,如果跟系統預設衝突,而且還是放在hash table裡面的,都可以用這個方法解決路徑的問題

陣列洗牌程式(shuffle array)

陣列如何把它的順序打亂,作出類似洗牌的效果,我一直都很頭痛,搞得非常的複雜。至從用了Ruby,Array物件包含 shuffle 方法之後,我就沒思考過陣列洗牌的問題了,反正Ruby幫我處理得好好的。 Ruby # 52張牌的牌堆 poker = (1..52).to_a # => [1, 2, 3, ... , 52] # 洗牌打亂 shuffled = poker.shuffle # => [22, 32, 12, ... # 也可以直接打亂原來的陣列 poker.shuffle! # => [39, 47, 3, ... Javascript Javascript我就頭痛了,我得自己寫洗牌的方法。我在網路上找到了這個演算法,仔細看了之後,才知道原來洗牌可以這麼簡單: // 原本for迴圈是一行程式,太難理解,這邊改寫成多行 function shuffle(o){ for(var j, x, i = o.length; i;){ j = Math.floor(Math.random() * i); // javascript的array是0-base // 所以迴圈第一次進入,--i後表示陣列最後一個位置。 x = o[--i]; o[i] = o[j]; o[j] = x; // 以上三行代表以x為temp, o[i], o[j]做交換 } return o; //回傳陣列,我一開始也看錯看成回傳0 }; 變數說明 引數o: 將被洗牌的陣列 for迴圈內 i : 將會從陣列的最後一個位置,慢慢往前移到第一個位置(但移到第一個位置時for迴圈不執行,因為Javascript的數值0也代表false,會離開迴圈。0代表flase這點跟Ruby不一樣) j : 將會被亂數選擇,選到要被交換的位置 x : 用來暫存o[i]的數值,幫助o[i]與o[j]做數值交換 就這樣從最後一個位置開始,依次往前隨機挑選一個位置與它交換(可能挑到自己,表示不交換),來達到洗牌的效果,陣列多大,就執行幾次,時間複雜度 O(n) ,...

Rails 在CSS裡使用圖片

暴力法 反正最後都會被編譯在public下面,可以下 rake assets:precompile 指令,看看最後圖片被放到哪裡去了,通常都在 public/asset 底下,而網頁伺服器的根目錄是 public/ 所以你的css就直接把圖片定位在 /assets/ 底下,例如: .your_class { background-image:url('/assets/your_img.png'); } 非常不建議用這個方法,程式碼非常不靈活 內嵌Ruby法 在Rails裡面,你的檔案想要內嵌Ruby,只要把檔名結尾加上 .erb ,就可以最常見的就是 page.html.erb ,但可沒這麼簡單唷,就連CSS檔以可以內嵌Ruby,一樣把你的CSS加上 .erb ,譬如 style.css.erb ,這樣CSS內就可以使用Ruby了。 既然可以使用Ruby了,那就大膽的把Rails內建的Helper拿出來用吧, asset_path("img.jpg") ,就行了,例如: .your_class { background-image:url('<%= asset_path("your_img.png") %>'); } 這樣至少靈活多了,至少你不用擔心Rails編譯之後,會把你的圖檔放到Public的哪裡去,被改了什麼檔名。 SCSS法 Rails預設使用SCSS,你打開你的Gemfile就可以看到了,預設已經有 gem 'sass-rails' ,在Rails的CSS裡面取圖,我推薦這個方法,因為這個方法程式碼最簡潔: .your_class { background-image: image-url("your_img.jpg"); } 發生什麼事?沒錯使用SCSS的話, image-url("your_img.jpg"); 就行了, image-url 是Rails的Helper,可別跟CSS原生的 background-image:url(your_img.jpg); 給搞混囉 .your_class { /* 這個是Rails的Helper */ back...

Ruby,檔案定期備份

我最近把資料庫系統換成了SQLite,直接放到RamDisk去執行。今天想要寫支程式,可以定時檢查RamDisk,裡面的sqlite檔有沒有變動,有變動就備份到硬碟去。於是使用Ruby寫下了: FILE_TO_CHECK = ARGV[0] FILE_TO_SAVE = ARGV[1] if !File.exists?(FILE_TO_SAVE) `cp #{FILE_TO_CHECK} #{FILE_TO_SAVE}` exit end check_file = File.new FILE_TO_CHECK save_file = File.new FILE_TO_SAVE if check_file.mtime > save_file.mtime `cp #{FILE_TO_CHECK} #{FILE_TO_SAVE}` end 不錯,不錯,想說這樣這隻程式可以放到crontab去,將來有同樣要檢查的檔案就編輯在crontab裡: 0 * * * * ruby /check_file.rb sinkfile sourcefile 不過做到這邊,突然想到,安裝 rsync 不就行了,直接 0 * * * * rsync sinkfile sourcefile rsync就是檢查檔案有無更動,有更動的才會複製,而且它是這麼老牌又穩定的lib了,呵呵,沒關係,就當做是在練習使用vim編輯器

Ruby,Time.new(自定時間格式)

Ruby 製作Time物件時,必須遵守一定的格式,譬如 Time.new(2014, 2, 13, 16, 30, 30, "+08:00") #=> 2014-02-13 16:30:30 +0800 Time.new 裡頭接受的參數從年,月,日,時,分,秒,時區,沒填的就預設是0,全部都沒填,那就給系統當前時間。那問題如果我們得到的時間是一個字串呢?例如我們有一個時間字串: 2014-02-13 16:50:47 +0800 這串文字當參數傳到到 Time.new 裡面只會出現錯誤訊息,難道要開始做苦工先字串解析,在放到 Time.new 裡面嗎? Time.strptime 用到字串解析也就太辛苦了,Ruby 的Time class提供一個strptime方法,可以直接定義time format, require 'time' 之後就可以使用了直接舉個例子: require 'time' t = Time.strptime("2014-02-13 16:50:47 +0800", "%Y-%m-%d %H:%M:%S %z") # => 2014-02-13 16:50:47 +0800 t.class # => Time 就直接得到了Time物件了,省去了字串解析的麻煩。 如果你需要的 DateTime 物件,也可以依法炮製: require 'time' dt = DateTime.strptime("2014-02-13 16:50:47 +0800", "%Y-%m-%d %H:%M:%S %z") # => #<DateTime: 2014-02-13T16:50:47+08:00 ((2456702j,31847s,0n),+28800s,2299161j)> dt.class # => DateTime 一樣可以直接得到 DateTime 物件。 如此就可以從各式各樣的時間格式,直接產生 Time 與 DateTime 物件了。來試個怪怪的格式: time = Time.strptime("22日2008年06月...

以Ruby語言執行系統命令

以Ruby語言去執行系統命令,有下列三種方式 exec args system args %x( args ) 或 ` args ` exec args exec 會中斷目前Ruby正在進行的process,然後執行系統命令。所以這個指令還蠻少用的,可以在irb裡面試試 root$ irb 2.1.0 :001 > exec 'pwd' /Users/wemee/Documents/GitHub/test root$ irb直接被中斷掉,然後進入bash執行pwd,所以大概只能用在linux的crontab裡面,定期執行一次就中斷 system args system 則會保留目前Ruby的process,執行完系統命令後,依照執行結果回傳: true: 執行成功 false: 執行失敗,譬如移動不存在的檔案 * nil: 執行的指令本身就打錯 system 'pwd' # => true system 'mv not_exist_file.txt foo.txt' # => false system 'wrong instruction' # => nil %x( args ) 或 ` args ` 這兩個也都不會重斷Ruby的process,並且執行完後,完整回傳系統命令回傳的字串。%x( args ) 或 ` args `兩種寫法執行結果都一樣,所以我都寫` args `,而且 ruby-style-guide 也多半認為少用%x比較好。 dir = `pwd` # => dir = "/Users/root/projects\n" files = `ls` # => files = "main.rb\ntemp.txt\ntest.txt\n" 這邊可以接著用 string.chmop 把最後面字尾那個"\n"刪掉,或用用 string.gsub("\n", " ") 把所有的"\n"替換成空白欄位。 最後,執行這些指令之前,記得檢查一下你的系統唷,很多linux的指令,跟win...

Rails, 上傳圖片或其他檔案

目前網路上關於如何在Ruby on Rails上傳檔案的方式,最熱門的就屬 paperclip 。 它處理圖檔必須用到convert指令,如果是Linux系統可以用 which convert 這個指令查看一下,系統裡面有沒有convert指令。如果沒有的話paperclip是推薦用 ImageMagick ,如果你有要上傳圖檔的話,就安裝一下吧,Linux可以用rpm安裝,MacOS就直接 brew install imagemagick 。 之後就使用gem安裝paperclip, gem "paperclip" 簡易使用方式 我是使用Rails 4,以下是Rails 4的場景。 產生資料庫欄位的部分它沒有實作在rails generate指令裡面,所以必須自己先產生Model, 然後再產生一個Migration,把欄位加上去之後,做rake db:migrate,例如: # 產生 "image" Model, 以及一個欄位"title" rails g model image title:string 打開所產生的model檔案(app/models/image.rb),為它增加一個file欄位關聯 class Image < ActiveRecord::Base has_attached_file :file, styles: {medium" "300x300>", thumb: "100x100>" }, default_url: "/images/:style/missing.png" validates_attachment_content_type :file, content_type: /\Aimage\/.*\Z/ end 但是只是先設定好Model關聯而已,我們實際上資料庫Table裡面並沒有file欄位,我們利用migration為他增加資料庫的file欄位: # 產生一個migration 準備增加file欄位 rails g migration image_add_column...

Ruby 併行賦值(Parallel Assignment)

前言 原本在找Ruby要怎麼交換兩個陣列的位置,找到一個很神奇的方法 class Array def swap!(a,b) self[a], self[b] = self[b], self[a] self end end 完全看不懂在幹嘛,如果是C語言,在同一行裡使用逗號,則表示從右到左依次執行而已,例如: int i,j; for(i=0,j=5;i<10;i++,j--); 在C語言這個迴圈共執行10次,每次都執行i++與j--,我把i++與j--寫在一起用逗號分開,其實也可以這麼寫 int i,j; for(i=0,j=5;i<10;){ i++; j--; } 有時候為了簡潔會塞在同一行。 可是Ruby這麼做,我全看不懂在幹嘛,在文章開頭的swap!函式裡頭,self[a]在我眼裡就是回傳self[a],然後將self[b]賦值self[b]等於沒變,最後再回傳self[a]而已,完全不清楚這是怎麼swap。 Parallel Assignment 查了一下 ruby-doc.com 之後,找到了 Parallel Assignment 這個關鍵字,終於搞清楚了,Ruby會將等號右邊所有的物件,按照相對位置賦值到等號左邊的參數,就叫做 Parallel Assignment ,譬如你要將x,y,z分別賦值1,2,3,在C語言你可能這麼寫 int x=1, y=2, z=3; 在Ruby裡面可以這麼寫 x,y,z = 1,2,3 就是如此而已,x,y,z就分別被賦值1,2,3。 當然,像我這種宅宅,一定還會好好地玩弄一下,我故意讓等號兩邊無法成對: 1: a,b = 1,2,3 # a=1, b=2 2: i,j,k = 1,2 # i=1, j=2, k=nil 行1,我原本以為b會被賦值為陣列[2,3],其實不用這麼古怪,Ruby設計直接把多出來的3丟掉,聰明的設計。 行2,我原本以為會出現錯誤訊息,但這也太嚴謹了,Ruby直接讓k=nil就行了,也是聰明的設計。 接著繼續惡搞一下,看他的語法有沒有靈活性: a,b = c=1, 2 # a=1, b=2, c=1 a,b = c,d = 1, 2, 3 ...

費氏數列(Fibonacci)

Fibonacci on wiki 使用遞回 /* * @parama n 第n項(n為正整數) * @return 第n項的值 */ function fibonacci(n) if n <= 1 return n return fibonacci(n-1) + fibonacci(n-1) end 使用迭代 /* * @parama n 第n項(n為正整數) * @return 第n項的值 */ function fibonacci(n) if n <= 1 return n int a=0, b=1,t; for i = 2 to n do t = a+b a = b b = t end return b end 使用cache優化遞回 /* * @parama n 第n項(n為正整數) * @return 第n項的值 */ function fibonacci(n) static Array cache ||= {0,1} if cache[n] not null return cache[n] cache[n] = fibonacci(n-1) + fibonacci(n-1) return cache[n] end 我在Github上使用Ruby的實作 Fork me on github

Markdown to HTML(Maruku)

Maruku on Github 本文網址 純Ruby做成,可將Markdown語法轉換成HTML,latex,md...等格式,以下簡單做點介紹。 安裝 gem install maruku 先在irb下面做點測試 require 'Maruku' # => true # 設定Markdown字串 markdown_string = '#大標題' # 使用Markdown字串 建立Maruku物件 doc = Maruku.new(markdown_string) #從Maruku物件輸出HTML文檔 doc.to_html # => "\n<h1 id=\"\">大標題</h1>\n" #從Maruku物件輸出latext文檔 doc.to_latext_document # => "\\documentclass{article}\n\n% ... 至於還有哪些Methods 自己用Ruby內建的methods語法來顯示 Maruku.methods # => 一堆class methods Maruku.new.methods # => 一堆instance methods 可以再加上正規表示式來尋找 Maruku.new.methods.grep(/html/) # => 一堆HTML相關的instance methods Maruku.new.methods.grep(/latex/) # => 一堆latex相關的instance methods 與Ruby on Rails結合 在Gemfile裡面加上 gem 'maruku' 譬如你自己做個Blog,讓人使用Markdown語法來寫文章。文件從資料庫取出來,直接傳給view顯示就行了,例如文章儲存在Post資料表的content欄位 Markdown_string = Post.first.content @doc = Maruku.new(Markdown_string) 在view...

Code Block for Blogger

Code Block for Blogger 我使用Markdonw語法打部落格文章,先轉換成Html之後,在貼到Blogger去,但是闡述程式碼的Code Block的區塊,產生出來的HTML是 <pre><code> ... </pre></code> 這些HTML貼到Blooger去,因為沒有CSS樣式裝飾,所以只有簡單的換行縮排,看起來有點像 引言 。 這邊我們可以自己加上CSS Style上去,讓他看起來漂亮點。首先Markdown轉出來的code block有兩種形式,一種是嵌入式的,譬如-> int i=0; <- 直接嵌入在行內,另一種是整個程式碼區塊,譬如: int i=0; /* 程式碼自己佔一個區塊 */ 嵌入式的程式碼區塊產生的HTML會是` int i=0; 整個程式碼區塊產生的HTML會是` int i=0; 差在 <pre> tag的有無,所以我們只要分別加上這兩個CSS Style給blooger的範本,就行了。可以自己寫,不過我直接在網路上找別人做好的: <style> code { background-color: #F9F9F9; border: 1px dashed #2F6FAB; color: black; /* line-height: 1.1em; padding: 1em;*/ } pre code { display: block; /* fixes a strange ie margin bug */ font-family: Courier New; font-size: 10pt; overflow:auto; background: #f0f0f0 url(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAASwCAYAAAAt7rCDAAAABHNCSVQICAgIfAhkiAAAAQJJREFUeJzt0kEKhDAMBdA4zFmbM+W0upqFOhXrDILwsimFR5pfMrXW5jhZr7PwRlxVX8//jNHrGhExjXzdu9c5IiIz+7iqVmB7Hwp4OMa2nhhwN/PRGEMBh3...