RubyによるMac OS Xデスクトップアプリケーション開発入門--Snow Leopard対応版

13,060 views

Published on

Rubyを使ったMacのデスクトップアプリケーション開発の概要を説明します。また、Mac OS X 10.6で導入されたGCDの概要とMacRubyからどのように使うのかを説明します。

Published in: Technology
0 Comments
10 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
13,060
On SlideShare
0
From Embeds
0
Number of Embeds
764
Actions
Shares
0
Downloads
55
Comments
0
Likes
10
Embeds 0
No embeds

No notes for slide

RubyによるMac OS Xデスクトップアプリケーション開発入門--Snow Leopard対応版

  1. 1. Ruby Mac OS X による デスクトップアプリケーション開発入門 -- Snow Leopard対応版 関西Ruby会議02 ­ 2009年11月7日 ネットワーク応用通信研究所 研究員 高尾 宏治<kouji@netlab.jp>2009年11月8日日曜日
  2. 2. Ruby Mac OS X による デスクトップアプリケーション開発入門 -- Snow Leopard対応版 関西Ruby会議02 ­ 2009年11月7日 ネットワーク応用通信研究所 研究員 高尾 宏治<kouji@netlab.jp>2009年11月8日日曜日
  3. 3. Ruby Mac OS X による デスクトップアプリケーション開発入門 -- Snow Leopard対応版 関西Ruby会議02 ­ 2009年11月7日 ネットワーク応用通信研究所 研究員 高尾 宏治<kouji@netlab.jp>2009年11月8日日曜日
  4. 4. RubyとMac2009年11月8日日曜日
  5. 5. RubyとMac2009年11月8日日曜日
  6. 6. RubyとMac OS X 10.2 Ruby 1.6.7 20022009年11月8日日曜日
  7. 7. RubyとMac OS X 10.2 Ruby 1.6.7 2005 2002 OS X 10.4 Ruby 1.8.22009年11月8日日曜日
  8. 8. RubyとMac OS X 10.5 Ruby 1.8.6 OS X 10.2 RubyCocoa Ruby 1.6.7 Rails 2005 2002 2007 OS X 10.4 Ruby 1.8.22009年11月8日日曜日
  9. 9. RubyとMac OS X 10.5 Ruby 1.8.6 OS X 10.2 RubyCocoa Ruby 1.6.7 Rails 2005 2009 2002 2007 OS X 10.4 OS X 10.6 Ruby 1.8.2 Ruby 1.8.7 RubyCocoa Rails2009年11月8日日曜日
  10. 10. RubyistとMacユーザ2009年11月8日日曜日
  11. 11. RubyistとMacユーザ Rubyは世界ランク10位 1位はJava http://www.tiobe.com/index.php/paperinfo/tpci/Ruby.html2009年11月8日日曜日
  12. 12. RubyistとMacユーザ Rubyは世界ランク10位 1位はJava Macの世界シェアは10%以下 90%以上がWindows http://www.tiobe.com/index.php/paperinfo/tpci/Ruby.html2009年11月8日日曜日
  13. 13. RubyistとMacユーザ Rubyは世界ランク10位 1位はJava Macの世界シェアは10%以下 90%以上がWindows 海外のRubyist≒Macユーザ Ruby Conf 2008に出席したある人の感想 http://www.tiobe.com/index.php/paperinfo/tpci/Ruby.html2009年11月8日日曜日
  14. 14. RubyistとMacユーザ Rubyは世界ランク10位 1位はJava Macの世界シェアは10%以下 90%以上がWindows 海外のRubyist≒Macユーザ Ruby Conf 2008に出席したある人の感想 NaClのMacユーザ=Rubyist http://www.tiobe.com/index.php/paperinfo/tpci/Ruby.html2009年11月8日日曜日
  15. 15. RubyによるMacアプリ開発2009年11月8日日曜日
  16. 16. RubyによるMacアプリ開発2009年11月8日日曜日
  17. 17. RubyによるMacアプリ開発 標準の開発ツール(Xcode)がRuby対応 ただし、Mac OS X 10.5だけ...2009年11月8日日曜日
  18. 18. RubyによるMacアプリ開発 標準の開発ツール(Xcode)がRuby対応 ただし、Mac OS X 10.5だけ... Rubyを使ってMacアプリを開発できる RubyとRubyCocoa MacRuby2009年11月8日日曜日
  19. 19. RubyによるMacアプリ開発 標準の開発ツール(Xcode)がRuby対応 ただし、Mac OS X 10.5だけ... Rubyを使ってMacアプリを開発できる RubyとRubyCocoa MacRuby とにかくGUI2009年11月8日日曜日
  20. 20. 開発ツール:Xcode2009年11月8日日曜日
  21. 21. 開発ツール:Xcode グループ2009年11月8日日曜日
  22. 22. 開発ツール:Xcode ファイル一覧 グループ2009年11月8日日曜日
  23. 23. 開発ツール:Xcode ファイル一覧 グループ エディタ2009年11月8日日曜日
  24. 24. 開発ツール:Interface Builder2009年11月8日日曜日
  25. 25. 開発ツール:Interface Builder メインウインドウ2009年11月8日日曜日
  26. 26. 開発ツール:Interface Builder メインウインドウ プロパティ2009年11月8日日曜日
  27. 27. 開発ツール:Interface Builder GUI部品 メインウインドウ プロパティ2009年11月8日日曜日
  28. 28. 公式開発言語:Objective-C2009年11月8日日曜日
  29. 29. 公式開発言語:Objective-C Macアプリの公式開発言語2009年11月8日日曜日
  30. 30. 公式開発言語:Objective-C Macアプリの公式開発言語 C言語にオブジェクト指向機能を追加 C言語の上位互換言語2009年11月8日日曜日
  31. 31. 公式開発言語:Objective-C Macアプリの公式開発言語 C言語にオブジェクト指向機能を追加 C言語の上位互換言語 C++とは異なるオブジェクトシステム Smalltalk由来 参考画像:CちゃんとSqueakのコラボ、絶妙なバランス http://www.limo.fumi2kick.com/forum/glang/glang17.jpg2009年11月8日日曜日
  32. 32. 公式開発言語:Objective-C Macアプリの公式開発言語 C言語にオブジェクト指向機能を追加 C言語の上位互換言語 C++とは異なるオブジェクトシステム Smalltalk由来 Cocoa:Objective-C用のライブラリ 参考画像:CちゃんとSqueakのコラボ、絶妙なバランス http://www.limo.fumi2kick.com/forum/glang/glang17.jpg2009年11月8日日曜日
  33. 33. RubyとObjective-C Ruby Objective-C self.width [self width];2009年11月8日日曜日
  34. 34. RubyとObjective-C Ruby Objective-C self.width [self width]; オブジェクトシステムはSmalltalk由来2009年11月8日日曜日
  35. 35. RubyとObjective-C Ruby Objective-C self.width [self width]; オブジェクトシステムはSmalltalk由来 相性は抜群 『RubyとCocoa(Objective-C)は、非常に幸運な組み合わせだったと言えるでしょう』                            -- 中川智史:RHC本より2009年11月8日日曜日
  36. 36. RubyとObjective-C Ruby Objective-C self.width [self width]; オブジェクトシステムはSmalltalk由来 相性は抜群 『RubyとCocoa(Objective-C)は、非常に幸運な組み合わせだったと言えるでしょう』                            -- 中川智史:RHC本より Rubyが理解できていればObjective-Cの理解は早い ただし、C言語の知識があることが前提2009年11月8日日曜日
  37. 37. RubyとObjective-C Ruby Objective-C self.width [self width]; オブジェクトシステムはSmalltalk由来 相性は抜群 『RubyとCocoa(Objective-C)は、非常に幸運な組み合わせだったと言えるでしょう』                            -- 中川智史:RHC本より Rubyが理解できていればObjective-Cの理解は早い ただし、C言語の知識があることが前提2009年11月8日日曜日
  38. 38. RubyとObjective-C Ruby Objective-C self.width [self width]; オブジェクトシステムはSmalltalk由来 相性は抜群 『RubyとCocoa(Objective-C)は、非常に幸運な組み合わせだったと言えるでしょう』                            -- 中川智史:RHC本より Rubyが理解できていればObjective-Cの理解は早い ただし、C言語の知識があることが前提2009年11月8日日曜日
  39. 39. RubyCocoaとMacRuby2009年11月8日日曜日
  40. 40. RubyCocoaとMacRuby RubyCocoa RubyとObjective-Cの橋渡しを行うライブラリ2009年11月8日日曜日
  41. 41. RubyCocoaとMacRuby RubyCocoa RubyとObjective-Cの橋渡しを行うライブラリ MacRuby Macに特化したRubyの処理系 http://www.macruby.org/2009年11月8日日曜日
  42. 42. RubyCocoaとMacRuby RubyCocoa RubyとObjective-Cの橋渡しを行うライブラリ MacRuby Macに特化したRubyの処理系 http://www.macruby.org/2009年11月8日日曜日
  43. 43. MacRubyの特徴 http://www.macruby.org/2009年11月8日日曜日
  44. 44. MacRubyの特徴 http://www.macruby.org/ CRuby 1.9ベース、100%互換を目標2009年11月8日日曜日
  45. 45. MacRubyの特徴 http://www.macruby.org/ CRuby 1.9ベース、100%互換を目標 LLVMで再実装されたVM2009年11月8日日曜日
  46. 46. MacRubyの特徴 http://www.macruby.org/ CRuby 1.9ベース、100%互換を目標 LLVMで再実装されたVM Rubyスクリプトをコンパイル可能2009年11月8日日曜日
  47. 47. MacRubyの特徴 http://www.macruby.org/ CRuby 1.9ベース、100%互換を目標 LLVMで再実装されたVM Rubyスクリプトをコンパイル可能 Mac OS Xにプリインストールされる(かも?) メイン開発者のLaurent Sansonetti氏はAppleの社員2009年11月8日日曜日
  48. 48. MacRubyのデモ class AppController attr_accessor :textField def hello(sender) @textField.stringValue = "Hello,MacRuby!" end end2009年11月8日日曜日
  49. 49. MacRubyの情報源2009年11月8日日曜日
  50. 50. MacRubyの情報源2009年11月8日日曜日
  51. 51. MacRubyの情報源2009年11月8日日曜日
  52. 52. MacRubyの情報源 『RubyによるMac OS Xデスクトップアプリケーション開発入門』 通称RHC本 ISBN: 978-4839931780 9月25日発売 3,570円(税込み)2009年11月8日日曜日
  53. 53. MacRubyの情報源 『RubyによるMac OS Xデスクトップアプリケーション開発入門』 通称RHC本 ISBN: 978-4839931780 9月25日発売 3,570円(税込み) MacRuby:世界に1冊2009年11月8日日曜日
  54. 54. MacRubyの情報源 『RubyによるMac OS Xデスクトップアプリケーション開発入門』 通称RHC本 ISBN: 978-4839931780 9月25日発売 3,570円(税込み) MacRuby:世界に1冊 RubyCocoa:日本に1冊2009年11月8日日曜日
  55. 55. MacRubyの情報源 『RubyによるMac OS Xデスクトップアプリケーション開発入門』 通称RHC本 ISBN: 978-4839931780 9月25日発売 3,570円(税込み) MacRuby:世界に1冊 RubyCocoa:日本に1冊 6F展示会場にてサイン会2009年11月8日日曜日
  56. 56. Macアプリの配布 Bodega:Macアプリ版AppStore2009年11月8日日曜日
  57. 57. Mac OS X 10.62009年11月8日日曜日
  58. 58. Mac OS X 10.6 http://www.apple.com/jp/macosx/uptodate/2009年11月8日日曜日
  59. 59. Mac OS X 10.6 2009/8/28リリース Snow Leopard:雪 http://www.apple.com/jp/macosx/uptodate/2009年11月8日日曜日
  60. 60. Mac OS X 10.6 2009/8/28リリース Snow Leopard:雪 GCD(Grand Central Dispatch) http://www.apple.com/jp/macosx/uptodate/2009年11月8日日曜日
  61. 61. Mac OS X 10.6 2009/8/28リリース Snow Leopard:雪 GCD(Grand Central Dispatch) OpenCL http://www.apple.com/jp/macosx/uptodate/2009年11月8日日曜日
  62. 62. Mac OS X 10.6 2009/8/28リリース Snow Leopard:雪 GCD(Grand Central Dispatch) OpenCL http://www.apple.com/jp/macosx/uptodate/2009年11月8日日曜日
  63. 63. GCDとは http://www.apple.com/jp/macosx/technology/2009年11月8日日曜日
  64. 64. GCDとは 並列処理を行うためのライブラリ http://www.apple.com/jp/macosx/technology/2009年11月8日日曜日
  65. 65. GCDとは 並列処理を行うためのライブラリ C言語の拡張とランタイム http://www.apple.com/jp/macosx/technology/2009年11月8日日曜日
  66. 66. GCDとは 並列処理を行うためのライブラリ C言語の拡張とランタイム MacRuby 0.5以降で利用できる http://www.apple.com/jp/macosx/technology/2009年11月8日日曜日
  67. 67. GCDのサンプル 素数の数を求める処理をGCDを使って実装する # 整数numが素数かどうかを判定する # 戻り値がtrueであれば素数 def prime?(num) (2...num).each do |i| return false if num % i == 0 end return true end2009年11月8日日曜日
  68. 68. GCDのサンプル # 10_000_000から10_000_299までの素数の数を求める prime = [] for i in 0...300 n = i + 10_000_000 prime << n if prime?(n) end puts(prime.length) $ time macruby count-prime.rb 14 macruby count-prime.rb 14.86s user 0.12s system 93% cpu 16.016 total2009年11月8日日曜日
  69. 69. GCDのサンプル # 10_000_000から10_000_299までの素数の数を求める prime = [] for i in 0...300 n = i + 10_000_000 prime << n if prime?(n) end puts(prime.length) #=> 142009年11月8日日曜日
  70. 70. GCDのサンプル # 10_000_000から10_000_299までの素数の数を求める prime = [] for i in 0...300 ループの並列処理 n = i + 10_000_000 prime << n if prime?(n) end puts(prime.length) #=> 142009年11月8日日曜日
  71. 71. GCDのサンプル # 10_000_000から10_000_299までの素数の数を求める prime = [] for i in 0...300 ループの並列処理 n = i + 10_000_000 prime << n if prime?(n) ロック end puts(prime.length) #=> 142009年11月8日日曜日
  72. 72. ループの並列処理 # 10_000_000から10_000_299までの素数の数を求める q = Dispatch::Queue.concurrent prime = [] q.apply(300) do |i| n = i + 10_000_000 prime << n if prime?(n) end puts(prime.length) #=> 142009年11月8日日曜日
  73. 73. ループの並列処理 # 10_000_000から10_000_299までの素数の数を求める q = Dispatch::Queue.concurrent 並列処理用のオブジェクトの取得 prime = [] q.apply(300) do |i| n = i + 10_000_000 prime << n if prime?(n) end puts(prime.length) #=> 142009年11月8日日曜日
  74. 74. ループの並列処理 # 10_000_000から10_000_299までの素数の数を求める q = Dispatch::Queue.concurrent 並列処理用のオブジェクトの取得 prime = [] q.apply(300) do |i| 並列ループ n = i + 10_000_000 prime << n if prime?(n) end puts(prime.length) #=> 142009年11月8日日曜日
  75. 75. グローバルディスパッチキュー グローバルディスパッチキュー 10000000 素数? 10000001 素数? 10000002 素数? … 10000299 素数? ワーカースレッド1 ワーカースレッド2 処理(ブロック)をディスパッチキューに登録 FIFO CPUのコア数などを考慮して自動で並列処理2009年11月8日日曜日
  76. 76. グローバルディスパッチキュー グローバルディスパッチキュー 10000000 素数? 10000001 素数? 10000002 素数? … 10000299 素数? ワーカースレッド1 ワーカースレッド2 10000000 素数? 処理(ブロック)をディスパッチキューに登録 FIFO CPUのコア数などを考慮して自動で並列処理2009年11月8日日曜日
  77. 77. グローバルディスパッチキュー グローバルディスパッチキュー 10000000 素数? 10000001 素数? 10000002 素数? … 10000299 素数? ワーカースレッド1 ワーカースレッド2 10000000 10000001 素数? 素数? 処理(ブロック)をディスパッチキューに登録 FIFO CPUのコア数などを考慮して自動で並列処理2009年11月8日日曜日
  78. 78. ループの並列処理の詳細 # 10_000_000から10_000_299までの素数の数を求める q = Dispatch::Queue.concurrent prime = [] q.apply(300) do n = i + 10_000_000 prime << n if prime?(n) end puts(prime.length) #=> 142009年11月8日日曜日
  79. 79. ループの並列処理の詳細 # 10_000_000から10_000_299までの素数の数を求める q = Dispatch::Queue.concurrent グローバルディスパッチキューの取得 prime = [] q.apply(300) do n = i + 10_000_000 prime << n if prime?(n) end puts(prime.length) #=> 142009年11月8日日曜日
  80. 80. ループの並列処理の詳細 # 10_000_000から10_000_299までの素数の数を求める q = Dispatch::Queue.concurrent グローバルディスパッチキューの取得 prime = [] q.apply(300) do n = i + 10_000_000 prime << n if prime?(n) end ブロックをグローバルディスパッチキューに登録 puts(prime.length) #=> 142009年11月8日日曜日
  81. 81. ロック # 10_000_000から10_000_299までの素数の数を求める q = Dispatch::Queue.concurrent prime = [] q_prime = Dispatch::Queue.new("com.example.prime") q.apply(300) do n = i + 10_000_000 q_prime.dispatch { prime << n } if prime?(n) end q_prime.dispatch(true) { puts(prime.length) }2009年11月8日日曜日
  82. 82. ロック # 10_000_000から10_000_299までの素数の数を求める q = Dispatch::Queue.concurrent prime = [] q_prime = Dispatch::Queue.new("com.example.prime") ロック用のオブジェクトの取得 q.apply(300) do n = i + 10_000_000 q_prime.dispatch { prime << n } if prime?(n) end q_prime.dispatch(true) { puts(prime.length) }2009年11月8日日曜日
  83. 83. ロック # 10_000_000から10_000_299までの素数の数を求める q = Dispatch::Queue.concurrent prime = [] q_prime = Dispatch::Queue.new("com.example.prime") ロック用のオブジェクトの取得 q.apply(300) do n = i + 10_000_000 q_prime.dispatch { prime << n } if prime?(n) ロック end q_prime.dispatch(true) { puts(prime.length) }2009年11月8日日曜日
  84. 84. ロック # 10_000_000から10_000_299までの素数の数を求める q = Dispatch::Queue.concurrent prime = [] q_prime = Dispatch::Queue.new("com.example.prime") ロック用のオブジェクトの取得 q.apply(300) do n = i + 10_000_000 q_prime.dispatch { prime << n } if prime?(n) ロック end q_prime.dispatch(true) { puts(prime.length) } 処理完了待ち2009年11月8日日曜日
  85. 85. プライベートディスパッチキュー グローバルディスパッチキュー 10000000 素数? 10000001 素数? 10000002 素数? … 10000299 素数? ワーカースレッド1 ワーカースレッド2 10000200 素数? プライベートディスパッチキュー 10000019 配列に追加 10000079 配列に追加 10000103 配列に追加 … ディスパッチキューに登録した順に1つずつ処理 プライベートキューは何個でも生成可能 ワーカースレッドはグローバルとプライベートで共通2009年11月8日日曜日
  86. 86. プライベートディスパッチキュー グローバルディスパッチキュー 10000000 素数? 10000001 素数? 10000002 素数? … 10000299 素数? ワーカースレッド1 ワーカースレッド2 10000019 10000200 配列に追加 素数? プライベートディスパッチキュー 10000019 配列に追加 10000079 配列に追加 10000103 配列に追加 … ディスパッチキューに登録した順に1つずつ処理 プライベートキューは何個でも生成可能 ワーカースレッドはグローバルとプライベートで共通2009年11月8日日曜日
  87. 87. プライベートディスパッチキュー グローバルディスパッチキュー 10000000 素数? 10000001 素数? 10000002 素数? … 10000299 素数? ワーカースレッド1 ワーカースレッド2 プライベートディスパッチキュー … 10000019 10000079 10000103 10000271 素数の 配列に追加 配列に追加 配列に追加 配列に追加 数を出力 ディスパッチキューに登録した順に1つずつ処理 プライベートキューは何個でも生成可能 ワーカースレッドはグローバルとプライベートで共通2009年11月8日日曜日
  88. 88. プライベートディスパッチキュー グローバルディスパッチキュー 10000000 素数? 10000001 素数? 10000002 素数? … 10000299 素数? ワーカースレッド1 ワーカースレッド2 10000103 配列に追加 プライベートディスパッチキュー … 10000019 10000079 10000103 10000271 素数の 配列に追加 配列に追加 配列に追加 配列に追加 数を出力 ディスパッチキューに登録した順に1つずつ処理 プライベートキューは何個でも生成可能 ワーカースレッドはグローバルとプライベートで共通2009年11月8日日曜日
  89. 89. ロックの詳細 # 10_000_000から10_000_299までの素数の数を求める q = Dispatch::Queue.concurrent prime = [] q_prime = Dispatch::Queue.new("com.example.prime") q.apply(300) do n = i + 10_000_000 q_prime.dispatch { prime << n } if prime?(n) end q_prime.dispatch(true) { puts(prime.length) }2009年11月8日日曜日
  90. 90. ロックの詳細 # 10_000_000から10_000_299までの素数の数を求める q = Dispatch::Queue.concurrent prime = [] q_prime = Dispatch::Queue.new("com.example.prime") プライベートディスパッチキューの生成 q.apply(300) do n = i + 10_000_000 q_prime.dispatch { prime << n } if prime?(n) end q_prime.dispatch(true) { puts(prime.length) }2009年11月8日日曜日
  91. 91. ロックの詳細 # 10_000_000から10_000_299までの素数の数を求める q = Dispatch::Queue.concurrent prime = [] q_prime = Dispatch::Queue.new("com.example.prime") プライベートディスパッチキューの生成 q.apply(300) do n = i + 10_000_000 q_prime.dispatch { prime << n } if prime?(n) 配列への要素追加をキューに登録(非同期) end q_prime.dispatch(true) { puts(prime.length) }2009年11月8日日曜日
  92. 92. ロックの詳細 # 10_000_000から10_000_299までの素数の数を求める q = Dispatch::Queue.concurrent prime = [] q_prime = Dispatch::Queue.new("com.example.prime") プライベートディスパッチキューの生成 q.apply(300) do n = i + 10_000_000 q_prime.dispatch { prime << n } if prime?(n) 配列への要素追加をキューに登録(非同期) end q_prime.dispatch(true) { puts(prime.length) } 素数の数の出力をキューに登録(同期)2009年11月8日日曜日
  93. 93. 使用したGCDのメソッド2009年11月8日日曜日
  94. 94. 使用したGCDのメソッド Dispatch::Queue.concurrent(priority = :default) 並列処理用のグローバルディスパッチキューを取得する2009年11月8日日曜日
  95. 95. 使用したGCDのメソッド Dispatch::Queue.concurrent(priority = :default) 並列処理用のグローバルディスパッチキューを取得する Dispatch::Queue#apply(amount_size) 並列ループを実行する2009年11月8日日曜日
  96. 96. 使用したGCDのメソッド Dispatch::Queue.concurrent(priority = :default) 並列処理用のグローバルディスパッチキューを取得する Dispatch::Queue#apply(amount_size) 並列ループを実行する Dispatch::Queue.new(label) シリアル処理用のプライベートディスパッチキューを生成する2009年11月8日日曜日
  97. 97. 使用したGCDのメソッド Dispatch::Queue.concurrent(priority = :default) 並列処理用のグローバルディスパッチキューを取得する Dispatch::Queue#apply(amount_size) 並列ループを実行する Dispatch::Queue.new(label) シリアル処理用のプライベートディスパッチキューを生成する Dispatch::Queue#dispatch(synchronicity = false) ディスパッチキューにブロックを登録する2009年11月8日日曜日
  98. 98. GCD vs. Thread 無駄に複数のスレッドを起動せずOS(中央)が制御 ロック不要 デッドロックが発生しない スレッド直接を使った方が効率がよいアプリが書けるが... 高い技術力やスレッドに関する知識が必要2009年11月8日日曜日
  99. 99. まとめ2009年11月8日日曜日
  100. 100. まとめ RubyとMac Rubyist≒Macユーザ2009年11月8日日曜日
  101. 101. まとめ RubyとMac Rubyist≒Macユーザ RubyによるMacアプリ開発 MacRubyを使おう2009年11月8日日曜日
  102. 102. まとめ RubyとMac Rubyist≒Macユーザ RubyによるMacアプリ開発 MacRubyを使おう Mac OS X 10.6 GCDは並列処理を行うライブラリ2009年11月8日日曜日
  103. 103. 質疑・応答 RHC本サポート:http://www.takao7.net/rhcbk/ kouji@takao7.net、@takaokouji、id:kouji0625 Pokenでハイホー! RHC本のサイン&販売会はこのあとすぐ!! 関西Ruby会議02 ­ 2009年11月7日 ネットワーク応用通信研究所 研究員 高尾 宏治<kouji@netlab.jp>2009年11月8日日曜日

×