高見龍

iOS app/Ruby/Rails Developer, 喜愛非主流的新玩具 :)

Private Setter in Ruby

image photo by Brad Higham

之前在 Public, Protected and Private Method in Ruby 這篇文章提到,在 Ruby 裡使用 private 方法的時候,不能明確的指出 receiver,以下面這段範例來說:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Dog
  def hello
    self.gossip
  end

  private
  def gossip
    puts "don't tell anyone!"
  end
end

snoopy = Dog.new
snoopy.hello        # => NoMethodError
snoopy.gossip       # => NoMethodError

在上面這段程式碼的第 13 行,因為它明確的指出 receiver (snoopy),所以執行這行程式碼會出現會出現 NoMethodError 的錯誤;而在第 3 行,即使 receiver 是 self 也一樣是不行的。

這是在 Ruby 裡面 private 方法的設計。

不過,今天剛好有朋友拿了一段程式碼給我看,才發現原來上面這個規則原來也是有例外的,舉個例子來說:

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
class Dog
  attr_accessor :name
  private :name, :name=

  def hello
    self.gossip
  end

  def greeting1
    self.name
  end

  def greeting2
    self.name = "Snoopy"
  end

  private
  def gossip
    puts "don't tell anyone!"
  end
end

snoopy = Dog.new
snoopy.hello         # => NoMethodError
snoopy.gossip        # => NoMethodError
snoopy.greeting1     # => NoMethodError
snoopy.greeting2     # => It Works!

在上面這段範例中用 attr_accessor 做了一個 name 的 getter 跟 setter,並且把 getter/setter 設定成 private。在第 10 行的地方呼叫了 private 的 getter,並且明確的指出 receiver 是 self,照規則來說會出現錯誤不意外,但第 14 行用類似的方法呼叫了 private 的 setter 卻沒有出錯!

的確 private 方法不能指出明確的 receiver,但 setter 算是這個規則的例外。因為你不在前面加 self 的話,像這樣:

1
2
3
  def greeting
    name = "Snoopy"
  end

這樣這個 name 不就變成區域變數的賦值了嗎?

想想看,如果在這裡呼叫 setter 不加 self 的話,那 Ruby 要怎麼分辨到底你是要呼叫 setter 還是區域變數?

話說回來,通常我們也不會沒事把 getter/setter 設定成 private,因為即然都做了 getter/setter 就是要給別人用的不是嗎? :)

Ruby 也可這樣寫

很榮幸有機會能受邀參加 Livehouse.in 舉辦的 Combo! 8 週連擊 活動,本次的講題是「Ruby 也可這樣寫」,主要是來聊聊一些 Ruby 有趣(或奇怪)的語法,以及可以用 Ruby 做些什麼事 (without Rails)。

image 投影片連結:https://speakerdeck.com/eddie/happy-programming-ruby

這並不是什麼新的主題,也不是很艱深的內容,只是發現最近在接手一些別人寫的 Ruby on Rails (以下簡稱 Rails)專案時發現,似乎不少人並不清楚 Ruby 一些特有的寫法,把 Ruby/Rails 當做 PHP 在寫,所以就想來試著介紹這個主題給大家,讓大家可以多認識一些 Ruby。

曾經寫過 Rails 的朋友也許寫過以下的語法來取得兩天前的時間:

1
2.days.ago

很多人以為這是 Ruby 的語法,但如果你打開 irb 這樣寫卻會出現 undefined method 'days' for 2:Fixnum 的錯誤訊息,那是因為其實不管是 days 或是 ago 方法,都不是內建在 Fixnum 類別的方法,而是 Rails(更精準說的話應該是 ActiveSupport 這個 gem) 透過 Open Class 的手法在原本內建的 Fixnum 類別加上了這些便利的方法。

我想大家都不否認 Ruby 的確是被 Rails 給帶紅起來的,不過一位日本的 Ruby 大前輩前田修吾在他的一份簡報「Rails 症候群の研究」提到「Ruby が何かわかっていない」(中譯:不知道 Ruby 是什麼東西),其實也是有點讓人擔心 XD。

Ruby 是什麼?

Ruby 是一種電腦程式語言,而 Rails 是一種使用 Ruby 建構出來的網站開發框架 (Web Framework),但 Rails 不是一種電腦程式語言。(當然要說 Rails 這樣的 DSL 也是一種語言也是 ok 的)

Ruby 是一種物件導向的程式語言,在 Ruby 裡的所有東西都是物件(幾乎),包括數字 5 也是,它是一個數字物件,所以我們在 Ruby 可以寫出像下面這樣的程式碼:

1
2
3
  5.times {
    puts "Hello, Ruby"
  }

聽說…

聽說 Ruby 很慢!

這個嘛,就要看跟誰比了,跟 C 語言比的話當然是一定慢的,但 Ruby 還沒有慢到不能用的地步(而且通常網站慢的地方都不是 Ruby 本身)。慢的地方如果真的很介意,也可改用其它方式來改善(例如改寫成 Extension)

曾經有朋友拿 Twitter 拋棄 Rails 而改用 Scala 為例說「你看看連 Twitter 都嫌 Rails 慢了!」,的確 Rails 並不是執行效率非常好的框架,但是回頭想想,貴單位的網站的用戶或流量做得到 Twitter 的 1% 嗎? 網站還沒做出來就先擔心撐不撐得住大流量可能也擔心得太早了一點 XD

PS:事實上現在 Twitter 的前端也還是用 Rails 在開發。

聽說寫 Ruby 要先買 Mac?

不知道從什麼時候開始開始流傳著「要寫 Ruby/Rails 要先買 Mac」這樣的都市傳說,特別是在 Ruby 相關的聚會活動或研討會,大家擺在桌上的幾乎是清一色的 Mac 筆電。其實開發 Ruby/Rails 專案真正合適的應該是 Linux/Ubuntu 的環境,畢竟最後的專案是佈署在這些平台上,而不是在你的 Mac 筆電裡。

那為什麼越來越多開發者都買了 Mac? 我想主要原因除了看起來比較潮之外,就是 Mac OS 本質上其實是 BSD 系統,它有內建的 terminal(或說是 shell) 可以用,對寫 Ruby/Rails 的開發者來說是很方便的。

Ruby 可以這樣寫

if modifier

以下是個很單純的 if 判斷:

1
2
3
4
age = 18
if age > 18
  puts "OK, I can see this movie"
end

在 Ruby 裡,像這樣單純的 if 判斷,我通常會把 if 放到後面,讓整個句字看起來更像一般的英文口語:

1
2
age = 18
puts "OK, I can see this movie" if age > 18

if..else.., case..when..

如果您曾經寫過其它程式語言,對以下的語法應該不陌生:

1
2
3
4
5
6
7
8
9
10
11
age = 16

if age >= 0 && age < 3 then
  puts "Baby"
elsif age >= 3 && age < 10 then
  puts "Kids"
elsif age >= 10 && age < 18 then
  puts "Teenager"
else
  puts "Oh Yeah!"
end

就是一連串的 if..else.. 啦,這樣的寫法沒有錯,也可以正常執行,但教課書通常會教說如果看到很多的 else if 的話,可考慮用 case..when 來處理:

1
2
3
4
5
6
7
8
9
10
11
12
age = 16

case
when age >= 0 && age < 3
  puts "Baby"
when age >= 3 && age < 10
  puts "Kids"
when age >= 10 && age < 18
  puts "Teenager"
else
  puts "Oh Yeah!"
end

但中間那段大於小於的比較,我會喜歡用 Ruby 裡內建的 Range 來比對,看起來會更容易懂:

1
2
3
4
5
6
7
8
9
10
11
12
age = 16

case age
when 0...3
  puts "Baby"
when 3...10
  puts "Kids"
when 10...18
  puts "Teenager"
else
  puts "Oh Yeah!"
end

multiple assignment

在 Ruby 可以一口氣指定好幾個變數的值:

1
x, y, z = 1, 2, 3

只要一行就可達到三行的效果。

在其它程式語言,如果想要交換 x 跟 y 兩個變數的值,通常會這樣做:

1
2
3
4
5
6
7
x = 1
y = 2

# 交換 x, y 的值
tmp = x
x = y
y = tmp

但在 Ruby 可以利用上面提到的變數多重指定的特性改寫成這樣:

1
2
3
4
5
x = 1
y = 2

# 交換 x, y 的值
x, y = y, x

相當簡單又容易懂。

unnecessary return

以下是我在之前某個 Rails 專案裡面看到的一段程式碼:

1
2
3
4
5
6
7
def is_even(n)
  if n % 2 == 0
    return true
  else
    return false
  end
end

這樣寫沒問題,只是一看就猜得出來可能是剛從別的程式語言轉過來沒多久。在 Ruby 裡的 return 並不是一定要寫的,所以上式再透過三元運算子的簡化可以變這樣:

1
2
3
def is_even(n)
  (n % 2 == 0) ? true : false
end

或可再精簡一些:

1
2
3
def is_even(n)
  n % 2 == 0
end

事實上,如果再熟悉 Ruby 一點的話就會發現其實數字類別本身就有帶一個判斷偶數或奇數的方法:

1
2
puts 2.even?  # => true
puts 4.odd?   # => false

Open Class

Ruby 的 Open Class 可以讓開發者任意的幫已存在的類別(甚至是內建類別)加功能,例如:

1
2
3
4
5
6
7
class String
  def say_hello
    "Hello, #{self}"
  end
end

puts "Ruby".say_hello   # => Hello, Ruby

事實上 Rails 也是大量的使用了這個手法來擴充 Ruby 的功能,像是 2.days.ago 就是個經典的例子(實作方式請見 ActiveSupport 的原始碼)

前面一開始也提到,在 Ruby 裡什麼東西都是物件,包括數字也是,所以其實連最簡單的 1 + 1,其實它是執行了 1 這個物件的 + 方法:

1
puts 1.+(1)

所以,透過 open class 的手法,甚至也可以去惡搞一下看起來最簡單的加法:

1
2
3
4
5
6
7
8
class Fixnum
  alias :ori_add :+
  def +(n)
    self.ori_add(n).ori_add(1)
  end
end

puts 1 + 1   # => 3

這樣一來就會在數學加法上偷偷的再加 1,像是 1 + 1 = 3, 2 + 2 = 5,以此類推。

不過,Open Class 好用歸好用,風險感覺不小,好像一個不小心就容易被自己或別人改到一些不該改的東西。所以後來 Ruby 有推出了一個叫做 Refinement 的概念:

1
2
3
4
5
6
7
8
9
10
11
12
module StringExtension
  refine String do
    def to_md5
      require "digest/md5"
      Digest::MD5.hexdigest(self)
    end
  end
end

using StringExtension

puts "Ruby".to_md5

Block

在 Ruby 裡,Block 可以用 do..end 的方式來寫,也可以用大括號來寫,雖然大部份候兩者是可以互相替換的,但有一些微妙的地方沒注意的話,可能會造成預期外的結果,詳情請見Do..End v.s Braces

Private method

在 Ruby 裡只要沒有特別聲明,所有的類別方法都是 public 的。如果想要在 Ruby 裡定義 private method 可以這樣做:

1
2
3
4
5
6
class Animal
  private
  def secret_method
    # ...
  end
end

或是這樣也可以:

1
2
3
4
5
6
7
class Animal
  def secret_method
    # ...
  end

  private :secret_method
end

看到第二種 private 的寫法,你應該就會發現其實 public、protected 以及 private 在 Ruby 裡並不是關鍵字或保留字,它只是個方法而已。

在 private 方法的定義上,Ruby 跟其它程式語言的定義有些不太一樣。在 Ruby 的 private 方法,是只要沒有明確的指出 recevier 就可以使用,所以即使是子類別也可使用父類別的 private 方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Animal
  private
  def secret_method
    puts "Don't tell anyone!"
  end
end

class Dog < Animal
  def hello
    secret_method
  end
end

Dog.new.hello  # => Don't tell anyone!

但其實 Ruby 的 private 方法也不是真的那麼 private:

1
2
3
4
5
6
7
8
9
10
class Animal
  def secret_method
    # ...
  end

  private :secret_method
end

a = Animal.new
a.send(:secret_method)

更多相關細節可參考 Public, Protected and Private Method in Ruby

參考資料:Message Passing

Dynamic Method

假設我們有一段程式碼長得像這樣:

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
class ComputerStore
  def get_cpu_info(workstation_id)
    # ...
  end

  def get_cpu_price(workstation_id)
    # ...
  end

  def get_mouse_info(workstation_id)
    # ...
  end

  def get_mouse_price(workstation_id)
    # ...
  end

  def get_keyboard_info(workstation_id)
    # ...
  end

  def get_keyboard_price(workstation_id)
    # ...
  end
end

有個軟體開發的原則叫做 DRY (Don’t Repeat Yourself),簡單的說就是不要一直寫重複的程式。在開發軟體的時候,如果可以把程式碼寫得 DRY 一點,日後在維護的時候也會輕鬆得多。

所以,如果上面這段程式碼假設每個 get_xxx_infoget_xxx_price 的方法實作內容都差不多,以 DRY 原則來看的話,上面這個看起來感覺就相當的「潮」(WET)啊,潮到出水了 XD

在這個時候就可以利用動態定義方法來整理這些看起來很重複的程式碼。在 Ruby 要動態的定義方法,可以用 define_method

1
2
3
4
5
define_method :hello do |param|
  puts "Hello, #{param}"
end

hello "Ruby"  # => Hello, Ruby

所以,原來上面那段看起來不太 DRY 的程式碼,可以整理成這樣:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class ComputerStore
  def self.set_component(component)
    define_method "get_#{component}_info" do |workstation_id|
      # ...
    end
    define_method "get_#{component}_price" do |workstation_id|
      # ...
    end
  end

  set_component :cpu
  set_component :mouse
  set_component :keyboard
end

還可以再簡化一些:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class ComputerStore
  def self.set_components(*components)
    components.each do |component|
      define_method "get_#{component}_info" do |workstation_id|
        # ...
      end
      define_method "get_#{component}_price" do |workstation_id|
        # ...
      end
    end
  end

  set_components :cpu, :mouse, :keyboard
end

這樣一來,以後如果要再加硬體,也只要在 set_components 後面加上去就行了,看起來應該比原來的好維護多了。

Method Missing

如果大家曾經使用過 Rails,也許多少有用過類似 Book.find_by_idBook.find_by_name 的神奇語法。你可能很好奇,為什麼明明你沒有定義這些方法,也一樣可以正常執行不會出錯?

其實,Ruby 在尋找方法的時候,會先往該物件的所屬類別找,找不到會再往它的父類別找(其實真正尋找方法的細節更複雜一些 XD),如果一直找不到,最後就會呼叫 method_missing 這個方法。

1
2
3
4
5
6
def method_missing(method_name, *args)
  puts "You just called a method #{method_name} with #{args}"
end

some_method_not_exist(1, 2, 3)
# => You just called a method some_method_not_exist with [1, 2, 3]

所以當你在適當的地方覆寫了 method_missing,就可以做出類似的效果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Book
  class << self
    def method_missing(method_name, *args)
      if method_name.to_s.start_with?("find_by")
        q = method_name.to_s.sub("find_by_", "")
        puts "find something by #{q}"
      else
        super
      end
    end
  end
end

Book.find_by_id    # => find something by id
Book.find_by_name  # => find something by name
Book.wtf           # => ERROR!

看到了嗎? 即使原先沒有定義 Book.find_by_idBook.find_by_name,在執行時候因為 find_by 開頭的方法被我自己寫的 method_missing 給攔了下來而不會出錯,但其它以外的方法則會呼叫內建的 method_missing 而噴出錯誤訊息。

有趣(或奇怪)的 Ruby 語法

寫程式有時候是件很悶的工作,偶爾寫點有趣的程式碼娛樂別人或自己也不錯。像是下面這個在 Trick 2013比賽中是「Most readable」的程式碼:

1
2
3
4
5
6
7
8
9
10
begin with an easy program.
you should be able to write
a program unless for you,
program in ruby language is
too difficult. At the end
of your journey towards the
ultimate program; you must
be a part of a programming
language. You will end if
you != program

寫得感覺像是一篇文章(其實內文無意義),但其它是一段可以正常執行不會發生錯誤的 Ruby 程式碼。下面這個則是「Best way to return true」:

1
$ruby.is_a?(Object){|oriented| language}

因為在 Ruby 的 global variable 預設值是 nil,又,在 Ruby 什麼東西都是物件,包括 nil 也是,所以 $ruby.is_a?(Object) 會回傳 true。至於後面傳入的 Block 因為不會被呼叫,所以傳什麼進去都無所謂了。

阿宅寫程式也可以很浪漫的:

1
It can be wonderful if "the world".end_with? "you"

或是:

1
I will love you until "the end of the world"

這其實只是透過邏輯短路(Short-circuit)玩的把戲,因為後面的 if 或 until 在經過評估之後都不會成立,所以前面的語法就算有錯也不會被執行到。

另外,其實 Ruby 的類別名稱也就只是個常數而已,所以這樣惡搞你的同事也是 ok 的…

1
2
3
4
5
class BookList < (rand > 0.1) ? Array : Hash
end

b = BookList.new
b << "Ruby"   # => 將有 10% 的機會發生錯誤

因為 Ruby 的方法名字不一定只能用英文字母,所以可以寫出像這樣的程式碼: image
看著看著就覺得餓了…

然後如果你知道 attr_accessor 其實也只是個會幫你產生一對 getter/setter 的類別方法的話,對產生的 getter/setter 不滿意或是想要再做些別的事話,也可以自己定義: image
這樣你就寫出了一個「可以永保青春的”方法”」了 XD

小結

看到這裡,你可能會覺得在 Ruby 變數不用宣告就可直接用,內建類別可以透過 Open Class 方式來惡搞,private 方法又一點都不 private,整個只像是僅供參考,這樣不會很恐怖嗎?

我想,開發者大多知道自己在做什麼。當初 Ruby 在設計的時候是採取相信開發者的立場,給開發者很大的彈性與自由,這其實也是我最後選擇 Ruby 的原因。

Ruby/Rails 被很多人認為是很魔術的程式語言或工具,但只要瞭解它是怎麼運作的,其實也沒真的非常神奇。技術不用學多,一、二門專精的練起來就已可不愁吃穿了。

最後, 引用一段最近在朋友的 Facebook 上看到的一段話:

“Difference between a master and a beginner? The master has failed more times than the beginner has even tried.”
“大師與新手之間的差別,就是大師失敗過的次數,比新手嘗試過的次數還多”

共勉之 :)

「有心人」之 Ruby 課程

image

記得在去年年初的時候,因為自己想找幾個一起打拼的伙伴而發起了一個「有心人」的活動,感謝大家的捧場以及社群朋友們的支持,活動順利結束。

然後,一直掛在嘴邊說要辦的「第二梯次」,總因為手邊的雜務而擱置。雖然後來斷斷續續的也有在中研院的自由軟體工作坊開一些 Ruby 的入門課或是在社群活動的分享,但就似乎變成有空才能開。

現在,我們成立了一家叫做五倍紅寶石的公司,在更多朋友的幫忙下,我們有更多的時間及資源可以來做推廣 Ruby 這件事了,畢竟推廣 Ruby 本來也是當初成立這家公司的最主要目的。

所以,在與夥伴們討論後,我們決定要來持續的無料推廣 Ruby,每個月固定至少會有個一天是 Ruby 推廣課程,希望可以讓更多人可以認識這個有趣可愛的程式語言。

詳情請見:http://5xruby.tw/courses/lets-learn-ruby-1

  • 上課地點:台北車站附近
  • 費用:0 元,惟上課學員需自備筆電,作業系統不限。

歡迎大家都可以開開心心的來認識、學習這個有趣的程式語言 :)

Code Swift with Vim

Swift 是今年 Apple 發表的程式語言,在發表的隔月就衝上了 TIOBE 排行榜的前 20 名。不過因為目前還在 Beta 中,所以除了改規格之外,開發工具的穩定性也還有待加強。

因為我已習慣用終端機 + Vim 工作,所以用 Vim 來練習寫 Swift 也是很正常的(誤)。不過其實真正的原因是之前 beta 版的 Xcode 太容易因為語法錯誤而當掉了。

Vim plugin

Vim 什麼沒有,plugin 最多了。不過因為 Swift 剛出來沒多久,外掛還不太多。我目前只有使用 vim-swift 這個 plugin,有支援語法 highlight。

Swift REPL

寫 Ruby/Rails 時已很習慣有 irb 之類的 REPL(Read–Eval–Print Loop) 可以用,Swift 這回也有提供 REPL。

因為在我電腦裡同時有安裝 Xcode 5 以及 Xcode 6 beta 5,所以在使用前得需先修改一下設定,開啟終端機後輸入:

$ sudo xcode-select -switch /Applications/Xcode6-Beta5.app

上面這個指令路徑設定可能會隨著 Xcode 6 的版本不同而需要做些調整。設定完之後,輸入:

$ xcrun swift

$ lldb --repl

即可進入 Swift 的 REPL 環境。

image

編譯

如果只是要寫個沒有畫面的小工具的程式,其實是不需要開 Xcode 的,只要一個簡單的 .swift 檔就可以了。

// 檔案 hello.swift
println("Hello, Swift!")

然後執行:

$ xcrun swift hello.swift

應該會在畫面上印出 Hello, Swift! 字樣。如果想要進行編譯,可執行:

$ xcrun swiftc hello.swift

這會在該目錄產生一個同名的 hello 執行檔(注意,是 swiftc 而不是 swift)。

註:以上是以 Xcode 6 Beta 5 為示範,在之前的版本的指令稍有不同。

自動執行

如果每次寫完存檔就要再執行一次 xcrun swift 也太辛苦了,工程師都是很懶的。有個不錯用的 gem 叫做 Guard可以幫你監視檔案的狀態,一但檔案有異動就跟著執行某些指令。

安裝 gem 是件輕鬆愉快的事,只要一行:

$ gem install guard-shell

如果安裝順利,下一步是請 guard 幫我們產生一個 Guardfile:

$ guard init shell

你應該可以在該目錄看到 Guardfile 檔案。我稍微做了些小修改如下:

1
2
3
4
5
6
guard :shell do
  watch(/(.*).swift/) do |m|
    puts "-" * 20
    puts `xcrun swift #{m[0]}`
  end
end

這個設定檔沒有很特別的東西,大概就是每次執行前先印出個分隔線,然後再印出 xcrun swift 的執行結果。接著只要在該目錄執行 guard 即可進入監看模式。

小結

因為 Vim 指法已習慣成肌肉記憶(muscle memory),所以我的 Xcode 也通常會安裝 XVim 讓 Xcode 可支援部份的 Vim 指令,不然完全沒辦法工作了。

是說像這樣用 Vim 寫 Swift,練練語法還 ok,但要靠 Vim 純手工刻出 iOS app 真的不是一般人能做到的事,所以其實我真正開發的時候,還是需要依賴 IDE 幫忙的,不然 method name 那麼長、參數那麼多,不靠 IDE 的自動完成,怎麼可能記得住。

即使如此,我個人還是覺得,可以用 Vim 寫程式,就是莫名的有種阿宅的浪漫啊 :)

五倍祝福,五倍的紅寶石

image

這回,您不需要自己斷開鎖鏈或斷開魂結,也不用燒毀什麼東西了 :)

「五倍紅寶石」是我與幾位台灣 Ruby 社群的朋友共同成立的一家公司,希望可以透過藉由教育訓練、企業培訓等課程,將 Ruby 推廣給更多的企業、開發者。

網站:http://5xruby.tw

緣起

我們是一群在台灣的 Ruby 程式語言的愛好者,每天的工作都是跟 Ruby / Rails 相關。

近一、二年來,Ruby / Rails 的人才需求增加,年薪超過百萬的高薪職缺紛紛出現,吸引越來越多人想要進入 Ruby / Rails 的領域。除自行學習以外,也很積極參加社群舉辦的聚會與分享、交流。

我們這幾年來持續的在台灣大專院校(成大、輔大、台北商專..等校) 開授 Ruby 以及 Rails 課程,觀察學生們的學習狀況,大多覺得 Ruby / Rails 其實並不難學,自己看書或是照著官網文件練習就能練到一定的程度。但要進階至可滿足實戰需求,不容易藉由自學可以短期達成,而是需要更多的實戰經驗,或是導師的帶領。也因此,在台灣,較資深或有經驗的 Ruby / Rails 開發者相當難找。

我們也走訪了一些企業的 IT 部門,請教他們為什麼不採用 Ruby / Rails 的原因,大多也是因為資深的 Ruby / Rails 的工程師難找,或是背後沒有商業公司的技術支援,遇到問題的時候不知道該找誰求救。

於是,我們這幾位愛好 Ruby 的朋友便開始討論「也許我們應該來成立一間專門提供 Ruby/Rails 相關的技術諮詢或是教育訓練的公司」。

我們最終的目的,是希望在台灣可以有越來越多的企業能了解或採用 Ruby 這個優雅、有趣,並且極具生產力的程式語言做為主要開發工具,更快速的實現您的想法。

感謝多位業界前輩、先進的支持與鼓勵:

Programmer 最有價值的是經驗值,「五倍紅寶石」的導師都是社群內數一數二的資深 Rubyist,由他們來帶領學員一探 Ruby 世界的神奇之處,實在是最佳選擇。

Victor LamEZTABLE 香港總經理

Eddie and his team are of the most dedicated Ruby evangelists I have ever come across. With their passion and professionalism, Ruby learners will leapfrog in their progress.

Jason HsuFounder of the Big Questions & TEDxTaipei

還在尋找專業的 Ruby/Rails 師資嗎?別懷疑了,台灣最頂尖的 Rubyist 盡在「五倍紅寶石」!

Felix Lin「搭配」網站創辦人

慕凡和龍哥是業界數一數二的 Ruby 大師,他們不光是底子深厚,也很懂得引導、訓練學習路上遇到挫折的 Ruby/Rails 學子。很慶幸有他們的協助讓我進入紅寶石的美妙世界。

花水木 Hana ChangCo-Founder and CEO of BountyHunter

選擇程式語言很重要,但選擇優秀的導師更重要!能跟擁有多年 Ruby/Rails 實戰經驗、活躍於社群的頂尖 Rubyist 學習,將一窺程式開發殿堂之藝術!我堅信:專業事讓專業的來,而專業的「五倍紅寶石」是寶藏,就等大家來挖掘。

謝耀輝 John SieAccuvally Inc.共同創辦人暨營運長

「五倍紅寶石」的導師們都是業界經驗豐富的實戰高手,提供的課程及咨詢絕對能讓你大幅省去自行摸索的時間。

Ben LinCEO@POP

曾有幸與徐曦與見龍一起工作,徐曦自我要求與向上進取的態度令人稱佩,見龍對危機處理與當責的責任感也值得稱許。「五倍紅寶石」的其他夥伴也是一時之選,相信這是一個很棒的組合。

呂元鐘 Max LuBuyble 國際精品購物 創辦人

公司名字的由來

為什麼公司會取這個看起來有點好笑的名字? 話說某天下午,我們幾個人在討論公司要取什麼名字…

「紅寶石股份有限公司? 聽起來好普通,而且會不會大家以為我們是珠寶商啊」。

就在大家一直想不到個有代表性又好記的名字的時候,突然來了一個「五倍紅寶石」,大家都笑了,但就在一陣狂笑之中,大家一致鼓掌通過決定要用這個聽起來有點 kuso 的名字了 XD

怎麼決定負責人是誰的?

即然是一家 Ruby 公司,Ruby 公司的事當然就是要交給 Ruby 解決。所以我們打開了 irb,輸入一段簡單的程式碼:

1
['A', 'B', 'C', 'D'].sample

嗯,我們的負責人這樣選出來了 XD

說明會

如果您對我們的課程有興趣,或是不知道「五倍紅寶石」到底是在賣什麼藥,歡迎您 6/5(星期四)晚上 19:30 前來參加我們舉辦的說明會,我們在現場將準備一些簡單的點心及飲料。

當然,只是要來閒聊或是找好陣子不見的朋友聚一聚也很歡迎。

  • 時間:2014/6/5 星期四 19:30
  • 地點:TED x Taipei Space
  • 地址:台北市金山南路一段 9 號 4 樓

請按這裡前往報名網站