2007/12/12 ema.

Slides:



Advertisements
Similar presentations
アルゴリズムとプログラミン グ (Algorithms and Programming) 第6回:クラスとインスタンス クラスの宣言 アクセス修飾子 インスタンスの生成 (new キーワード) this キーワード フィールドとメソッドの実際の定義と使い 方 クラスの宣言 アクセス修飾子 インスタンスの生成.
Advertisements

プログラミング Ⅱ 第2回 第1回(プログラミングⅠの復 習) の解説. プログラムの作り方 いきなり完全版を作るのではなく,だんだ んふくらませていきます. TicTa cToe1.
わんくま同盟 福岡勉強会 #4 yield について るーごん. わんくま同盟 福岡勉強会 #4 自己紹介 日本一人口が少ない県に住んでいます。 一昨年まで、ちょっと福岡に住みました。 仕事は主に dbMAGIC 。 プログラミング言語はよく分かりません。 好きなもの ポケモン、ファイブマン、ジェットマン、
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第3回 配列(1) 情報・知能工学系 山本一公
(Rubyistのための) 超音速:ML入門
JavaScript プログラミング入門 2006/11/10 神津.
プログラミング基礎I(再) 山元進.
プログラミング言語としてのR 情報知能学科 白井 英俊.
~手続き指向からオブジェクト指向へ(Ⅰ)~
12.3,E,-15, 12.3,E5,+,=, >,<,…,
アルゴリズムとプログラミング (Algorithms and Programming)
実行時のメモリ構造(1) Jasminの基礎とフレーム内動作
Lightweight Language Weekend ls-lRシェル
VBA H106077 寺沢友宏.
基礎プログラミングおよび演習 第9回
プログラミング基礎I(再) 山元進.
最適化ソルバーのための Python言語入門
第2回:Javaの変数と型の宣言 プログラミングII 2007年10月2日.
Ruby勉強会(第1回) 2006/06/29 竹内豪.
第6章 2重ループ&配列 2重ループと配列をやります.
プログラミング論 II 電卓,逆ポーランド記法電卓
の まとめ 2007/04/02 (Mon) / d;id:hzkr
ピカチュウによる オブジェクト指向入門 (新版)
情報処理技法 (Javaプログラミング)2 第2回 前期の復習(2)
第13回 ハッシュテーブルを使ったプログラム ~高速に検索するには?~.
細かい粒度でコードの再利用を可能とするメソッド内メソッドのJava言語への導入
11.6 ランダムアクセスファイル 11.7 StreamTokenizerクラス
プログラミング言語入門 手続き型言語としてのJava
図書館職員のための アプリケーション開発講習会
暗黙的に型付けされる構造体の Java言語への導入
第10回関数 Ⅱ (ローカル変数とスコープ).
プログラミング論 II 2008年10月30日 文字列
プログラミング言語入門.
アルゴリズムとプログラミング (Algorithms and Programming)
プログラミング演習I 2003年6月25日(第10回) 木村巌.
お仕事にまったく役にたたない内容のコードレビューやりたいと思います。
地域情報学 C言語プログラミング 第1回 導入、変数、型変換、printf関数 2016年11月11日
PHP 概要 担当 岡村耕二 月曜日 2限 平成22年度 情報科学III (理系コア科目・2年生)
プログラミング言語論 第四回 理工学部 情報システム工学科 新田直也.
第5章 計算とプログラム 本章で説明すること ・計算の概観と記述法 ・代表的な計算モデル ・プログラムとプログラム言語.
アルゴリズムとデータ構造 2011年7月8日課題の復習
プログラミング入門.
C言語 はじめに 2016年 吉田研究室.
オブジェクト プログラミング 第2回 プログラムの基本.
C言語ファミリー C# 高級言語(抽象的) Java オブジェクト指向 C++ C 機械語(原始的)
アルゴリズムとプログラミング (Algorithms and Programming)
★C++/オブジェクト指向実践企画★ Othelloゲーム作成
プログラミング言語論 第十三回 理工学部 情報システム工学科 新田直也.
プログラミング言語論 第十一回 理工学部 情報システム工学科 新田直也.
計算機プログラミングI 木曜日 1時限・5時限 担当: 増原英彦 第1回 2002年10月10日(木)
復習 Cにおけるループからの脱出と制御 break ループを強制終了する.if文と組み合わせて利用するのが一般的. continue
計算機プログラミングI 第3回 プリミティブ値 クラスメソッド クラス変数 式と演算 変数の利用
アルゴリズムとプログラミング (Algorithms and Programming)
オブジェクト指向言語論 第五回 知能情報学部 新田直也.
情報処理Ⅱ 第7回 2004年11月16日(火).
JAVA入門⑥ クラスとインスタンス.
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
コンパイラ 2012年10月11日
ソフトウェア工学 知能情報学部 新田直也.
Javaとは Javaとはオブジェクト指向言語でJava VM(Java仮想マシン)と呼ばれるプログラム上で動作します。
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
情報処理Ⅱ 2005年11月25日(金).
プログラミング入門2 第5回 配列 変数宣言、初期化について
情報処理Ⅱ 小テスト 2005年2月1日(火).
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
岩村雅一 知能情報工学演習I 第7回(後半第1回) 岩村雅一
計算機プログラミングI 第2回 2002年10月17日(木) 履習登録 複習 ライブラリの利用 (2.6-7) 式・値・代入 (2.6-8)
計算機プログラミングI 第10回 2002年12月19日(木) メソッドの再定義と動的結合 クイズ メソッドの再定義 (オーバーライド)
計算機プログラミングI 第5回 2002年11月7日(木) 配列: 沢山のデータをまとめたデータ どんなものか どうやって使うのか
情報処理技法(Javaプログラミング)1 第8回 同じ処理を何回も繰り返すには?
Presentation transcript:

2007/12/12 ema

Agenda オブジェクト指向 ブロック(イテレータ) クラス irb 文法 変数 三目並べ : Tick-tac-toe

オブジェクト 指向って?

!!! WARNING !!!

!!! WARNING !!! プログラミングの経験を前提にしていますが 頭をまっさらにして聞いてください 「C++ / Java ではこうだよね?」 というのは邪魔になりかねません 後、一般的な入門書とは毛色を変えています 詳細は入門書を読み直してください

3つのオブジェクト指向 「メッセージング」 by アラン・ケイ 影響を受けている言語 : Smalltalk、Ruby など 影響を受けている言語 : C++ など 「手続きによる抽象化手法」 by ウィリアム・クック オブジェクト指向の概念の発明者は誰ですか? http://d.hatena.ne.jp/sumim/20040525/p1

登 場 人 物

すべてがオブジェクト 「メッセージング」の考え方 インスタンス メッセージ リテラル すべてがオブジェクト オブジェクト同士はメッセージをやりとりする インスタンス メッセージ リテラル

インスタンスありきと神は語りき 計算してください

インスタンス / オブジェクト 計算してください コンピュータ上にある何か

メッセージ 計算してください オブジェクト同士のやりとり

実 例

1 . to_s : 数字の「1」を文字列に ソースコード オブジェクト空間 1 . to_s Rubyインタプリタ

リテラルという魔法 1 「1」の インスタンスを生成 1 . to_s

メッセージング(メソッド呼び出し) 1 to_s して下さい 1 . to_s

結果が返ってくる "1" を生成 1 "1" "1" だよ 1 . to_s

評価終了 : 1.to_s => "1" 1 "1" "1" 評価の結果 "1" でした

式と評価 式 オブジェクト 1 . to_s “1” 評価 先ほどの 一連の流れのこと Ruby のプログラムは 式 と 評価 の繰り返し Evaluate : 値にする,推し測る,実行する 式 オブジェクト 1 . to_s “1” 評価 先ほどの 一連の流れのこと

メソッド オブジェクトに対する操作 「Ruby 用語集」より 先ほどの例は「to_s」メソッドを呼び出していた 厳密には関数とは違うけど、似たようなもの

オブジェクト と メソッド呼び出し 1 to_s して下さい 1 . to_s

ブ ロ ッ ク (イテレータ)

= 例: 10 回繰り返し 10.times { |i| puts i } ブロック 10.times do |i| puts i end ブロック内が実行される

例: each - ループする 1 each do |i| puts i end 2 3

配列 から 配列 を作る A 変換 B

map : 関数型言語のノリ [ 1, 2, 3 ].map do |i| i * 2 end 僕が map の意義を理解したのは割と最近 だから、無茶をしようとしているのかも? でも、map そのものは自然なはず [ 1, 2, 3 ].map do |i| i * 2 end

配列 : map / collect - 変換 1 2 map do |i| i * 2 end 2 4 3 6 各要素を二倍する

配列 : map / collect - 変換 [1, 2, 3] を元に新しい配列を作る 要素を二倍 [ 1, 2, 3 ].map { |i| i * 2 } [ 1, 2, 3 ] ×2 [ 2, 4, 6 ]

[1, 2, 3] . map { |i| I * 2 } ブロック (イテレータ) [1,2,3].map { |i| i*2 }

[1, 2, 3] の生成 - リテラルらるる [1, 2, 3] の インスタンスを生成 [1,2,3].map { |i| i*2 }

メッセージング 結果格納用の 配列を生成 { |i| i*2 } を使って map して下さい 1 2 { |i| i*2 } を使って map して下さい 3 [1,2,3].map { |i| i*2 }

ブロックの評価 : 「1」その 1 「i = 1」で 「i * 2」を 評価して下さい [1,2,3].map { |i| i*2 } 1

ブロックの評価 : 「1」その 2 2 1 2 結果を格納 3 2 でした [1,2,3].map { |i| i*2 }

ブロックの評価 : 「2」その 1 「i = 2」で 「i * 2」を 評価して下さい [1,2,3].map { |i| i*2 } 2

ブロックの評価 : 「2」その 2 2 4 1 2 結果を格納 3 4 でした [1,2,3].map { |i| i*2 }

ブロックの評価 : 「3」その 1 「i = 3」で 「i * 2」を 評価して下さい [1,2,3].map { |i| i*2 } 2 4 1 2 「i = 3」で 「i * 2」を 評価して下さい 3 [1,2,3].map { |i| i*2 }

ブロックの評価 : 「3」その 2 2 4 1 6 2 結果を格納 3 6 でした [1,2,3].map { |i| i*2 }

ブロックの評価 : 「3」その 2 2 4 1 6 2 3 [2, 4, 6] だよ [1,2,3].map { |i| i*2 }

評価終了 2 4 1 6 2 3 評価の結果 [2, 4, 6] でした [2, 4, 6]

ガ ベ ー ジ コレクション

ガベージコレクション (GC) "1" 1 役目を終えたね

ク ラ ス

1.to_s ふたたび 1 to_s 1 . to_s "1" だよ

実際には、Fixnum クラスが処理 to_s 1 Fixnum to_s 1 . to_s "1" だよ

実際には、Fixnum クラスが処理 to_s 1 2 Fixnum to_s 2 . to_s "2" だよ

インスタンス毎は非効率 インスタンス毎にメソッドを用意するのは非効率 共通の処理/特徴をまとめたのがクラス String(文字列), Array(配列)など

継承 : クラスの属性を受け継ぐ sub class super class 基本的にはメッセージを super class に丸投げ Class A Class B super class 基本的にはメッセージを super class に丸投げ

オーバーライド / 再定義 Class A Class B 特定メッセージのみ 反応を変える

i r b

Interactive RuBy irb コマンド Ruby の式を簡単に入力/実行するためのツール Ubuntu などだと標準で入ってないので sudo aptitude install irb などとしてインストール

Interactive RuBy 文 評価結果 irb(main):001:0> a = "1" => "1" irb(main):002:0> b = a irb(main):003:0> a += "b" => "1b" irb(main):004:0> b 文 評価結果

休 憩 質問無い?

Agenda オブジェクト指向 ブロック(イテレータ) クラス irb 文法 変数 三目並べ : Tick-tac-toe

文 法

特徴 すべてがオブジェクト ほぼすべての文が値を返す 改行が文の切り替わり。; は書かない慣習 メソッド呼び出しの ( ) は必須ではない { } と do end はほぼ等価

if - もし○○なら if month == 1 "睦月" elsif month == 2 "如月" # ... 中略 ... else # エラー end

偽になるのは false と nil だけ if 0 puts "hoge" hoge が表示される end 残りは全て 真 になる(0 も!) if 0 puts "hoge" end hoge が表示される

nil って? C でいうところの null 未初期化値

case - when case month when 1 then "睦月" when 2 then "如月" # ... 中略 ... when 12 then "師走" else # エラー end

unless - もし、○○じゃなかったら unless line.empty? # 空でなければ end

while / until - 繰り返し while line = gets puts line end

break / next while line = gets # # で始まる行はコメント next if line[0] =~ /^#/ # __END__ だけの行がきたら終わる break if line == '__END__' puts line end

修飾子 return if str.empty? retry unless retry_count >= 20 この2つはよく使う。後ろから条件を指定 ぶっちゃけ好みの問題

メソッド定義 def japanese_month_name( month ) # ... 中略 ... end メソッド名 引数

制御構造も値を返す def japanese_month_name( month ) case month when 1 then "睦月" # ... 中略 ... when 12 then "師走" else # エラー end

メソッド呼び出し a = japanese_month_name( 1 ) b = japanese_month_name 2 ( ) は、あっても無くても良い 付けるかどうかは気分次第 読みやすいと感じる方で

Array

配列って? オブジェクトを複数格納できるもの 何でもいれれる、混在できる a[0] a[1] a[2] a[n-1] 1 "foo" /bar/ n-2 n-1 n … a[-n] a[-3] a[-2] a[-1]

サイズ n の配列への添字アクセス a.length / a.size a[0] a[1] a[2] a[n-1] 1 2 3 n-2 … a[-n] a[-3] a[-2] a[-1] a.first a.last a.length / a.size

配列式 [ 1, 2, 3 ] # 1, 2, 3 の配列を作る [ [ 1, 2 ], [ 3, 4 ] ] # ネストも可能 [ 1, 2, 3 ] # 1, 2, 3 の配列を作る [ [ 1, 2 ], [ 3, 4 ] ] # ネストも可能 %w(one two three) # ["one","two","three"]

Hash

ハッシュって? オブジェクトを複数格納できるもの 配列の添え字は数字だけ。 ハッシュの添字はオブジェクトなら何でも "foo" h["name"] 20 h["age"] "male" h["sex"]

ハッシュ式 { "name" => "foo", "age" => 20, "sex" => "male" }

配列とハッシュの組み合わせ わざわざクラスや構造体を用意せずに 配列とハッシュの組み合わせだけで データ構造を実現することが多い

String

文字列 "hoge" 'hoge' #{式} で文字列中に値を埋め込める ex. "hoge #{1}" # => "hoge1" 文字列中に値を埋め込むことは出来ない

%記法による文字列 %q|"hoge"| # => "hoge" %Q["hoge#{i}"] # => "hoge1" " や ' などを文字列に入れたいときに重宝 %q|"hoge"| # => "hoge" %Q["hoge#{i}"] # => "hoge1"

リテラル

その他のリテラル - 魔法の呪文 Symbol : :hoge Fixnum : 1 や -1 や 0xff や ?a Float : 1.0 や 1.2e-3 Bignum : 100_000_000_000_000_000 Range : 1..10 や 1...10 Regexp : /hoge/

リテラルの評価 → オブジェクト 配列式 オブジェクト [1, 2, 3] [1, 2, 3] 評価 文字列リテラル オブジェクト %Q|no: #{i}| "no 1" 評価

変 数

変数の種類と、名前の規則 ローカル変数 : 小文字 or _ で始まる 定数 : 大文字 で始まる 定数 : 大文字 で始まる 擬似変数 : self, nil, true, false, ... インスタンス変数 : @ で始まる クラス変数 : @@ で始まる グローバル変数 : $ で始まる

変数のイメージ : 矢印 [1, 2] a a = [1, 2] b = a a << 3

変数のイメージ [1, 2] a b a = [1, 2] b = a a << 3

変数のイメージ [1, 2, 3] a b a = [1, 2] b = a a << 3

数値や文字列はコピーされる 1 a a = 1 b = a a += 1

数値や文字列はコピーされる 1 a 1 b a = 1 b = a a += 1

数値や文字列はコピーされる 2 a 1 b a = 1 b = a a += 1

三目並べ作り Tick-Tac-Toe

実際のコードを読む 実際のコードを読む 出てくる文法的要素を随時解説 三目並べ(Tick-tac-toe)を作ってみた

設計 : 入力と出力を決める 入出力は、コマンドライン すなわち、標準入出力を使う

実行時のイメージ o のターンです x> 1 y> 3 y x:1 2 3 +-+-+-+ 1 |o|o|x| 2 |x|x| | 3 |o| | |

登場人物を洗い出す - クラス候補 ○マス ×マス プレーヤ プレーヤ 空白マス ゲームルール 盤面

今回は盤面以外全部クラスにします Maru Batu Player Player Free TickTacToe

以下,部分部分をみていきます ソースコードは全部で 160 行ほど 以下,部分部分にわけて読んでいきます

クラスの書き方 class クラス名(大文字で始める) # メソッド定義 def hoge end クラス名は大文字で始める

duck typing – アヒル風ならアヒル Batu maru? Free Maru メッセージに 答えてくれれば 何でも良い If it walks like a duck and quacks like a duck, it must be a duck. (アヒルのように歩き, アヒルのように鳴くものはアヒルに違いない) まつもと直伝 プログラミングのオキテ 第4回(3) http://itpro.nikkeibp.co.jp/article/COLUMN/20050926/221633/

Maru, Batu, Free - マス目クラス 末尾に「?」が ついてるのは true / false を返す慣習 class Maru def maru?; true ; end def batu?; false; end def free?; false; end def to_s ; "o" ; end end class Batu def maru?; false; end def batu?; true ; end def free?; false; end def to_s ; "x" ; end end class Free def maru?; false; end def batu?; false; end def free?; true ; end def to_s ; " " ; end end 末尾に「?」が ついてるのは true / false を返す慣習

フロー

main def main game = TickTacToe.new # 初期化 loop do puts game.to_s # 盤面表示 game.main # 置いて、プレーヤ交代 break if game.end? # 終了? end game.display_result # 結果表示 # ... 中略 ... main # main 呼び出し

TickTacToe#main def main x, y = current_player.input # 入力 put( x, y ) # 置く change_player # プレーヤ交代 end

TickTacToe#initialize - 初期化 class TickTacToe def initialize @players = [ Player.new('x'), Player.new('o') ] @current_player_index = 0 @field = Array.new( 3 ) do Array.new( 3 ) { Free.new } end @result = NOT_END

TickTacToe#initialize オブジェクトが初期化されるときに呼ばれる 例えば「 TickTacToe.new 」を呼ぶと, 「 TickTacToe オブジェクト 」 が生成されて, 「 TickTacToe#initialize 」 が実行される TickTacToe.new TickTacToe#initialize

インスタンス変数 TickTacToe TickTacToe @ から始まる変数 インスタンスごとに変数を持つ players field result TickTacToe field players result

TickTacToe#initialize - 初期化 class TickTacToe def initialize @players = [ Player.new('x'), Player.new('o') ] @current_player_index = 0 @field = Array.new( 3 ) do Array.new( 3 ) { Free.new } end @result = NOT_END

@field の中身 3 x 3 の配列 配列の中に配列 Free Free Free @field[0] Free Free Free

なぜ次のコードでは駄目か? Free.new は 1 回しか評価されず 同じオブジェクトを 参照してしまう Free @field = Array.new( 3 ) do Array.new( 3, Free.new ) end Free.new は 1 回しか評価されず 同じオブジェクトを 参照してしまう Free

TickTacToe - フィールド管理 return なくても 値が返る 名前は _ で区切る慣習 def cell( x, y ) @field[y][x] end def set_cell( x, y, obj ) @field[y][x] = obj return なくても 値が返る 名前は _ で区切る慣習

TickTacToe#put def put( x, y ) if @current_player_index == 0 set_cell( x, y, Batu.new ) else set_cell( x, y, Maru.new ) end

TickTacToe - プレーヤ管理 def current_player @players[ @current_player_index ] end def change_player if @current_player_index == 0 @current_player_index = 1 else @current_player_index = 0

TickTacToe#end? その1 - 終了? BATU_WIN = 0; MARU_WIN = 1 DRAW = 2; NOT_END = 3 def end? # 三目並ぶ可能性のある座標組合せの一覧を作る candidates = [ ] candidates << [ [0,0], [1,1], [2,2] ] # 斜め candidates << [ [2,0], [1,1], [0,2] ] # 斜め 3.times do |i| candidates << [ [i,0], [i,1], [i,2] ] # 縦 candidates << [ [0,i], [1,i], [2,i] ] # 横 end

配列 : push - 末尾に追加 a.push n a << n push 配列の大きさは 勝手に拡張される 1 2 3 … n 配列の大きさは 勝手に拡張される

TickTacToe#end? その2 - 終了? candidates.each do |candidate| if candidate.all? { |x,y| cell(x,y).batu? } @result = BATU_WIN; return true end if candidate.all? { |x,y| cell(x,y).maru? } @result = MARU_WIN; return true # 決着がついて無くて,全部埋まれば引き分け @result = DRAW if @result==NOT_END && filled? return @result != NOT_END

TickTacToe#end? その3 - filled? candidates.each do |candidate| if candidate.all? { |x,y| cell(x,y).batu? } @result = BATU_WIN; return true end if candidate.all? { |x,y| cell(x,y).maru? } @result = MARU_WIN; return true # 決着がついて無くて,全部埋まれば引き分け @result = DRAW if @result==NOT_END && filled? return @result != NOT_END

TickTacToe#filled? - 埋まった? def filled? @field.all? do |row| row.all? do |cell| ! cell.free? end class Maru def free?; false; end end class Batu def free?; false; end end class Free def free?; true ; end end

all? - 全部が true? Batu Maru Batu Batu Maru Maru Maru Batu Batu @field.all? do |row| row.all? do |cell| ! cell.free? end Batu Maru Batu Batu Maru Maru Maru Batu Batu

all? - 全部が true? 順番に評価される true Batu true true Maru Batu true Batu Maru @field.all? do |row| row.all? do |cell| ! cell.free? end Batu true true Maru Batu true Batu Maru Maru 順番に評価される Maru Batu Batu

all? - 全部が true? 1行ずつ true true true true true true Batu Maru Maru @field.all? do |row| row.all? do |cell| ! cell.free? end true true true true true Batu Maru Maru 1行ずつ Maru Batu Batu

all? - 全部が true? true true true true true true true true true true @field.all? do |row| row.all? do |cell| ! cell.free? end true true true true true true true true true Maru Batu Batu

all? - 全部が true? true @field.all? do |row| row.all? do |cell| ! cell.free? end

TickTacToe#end? その4 - all? candidates.each do |candidate| if candidate.all? { |x,y| cell(x,y).batu? } @result = BATU_WIN; break end if candidate.all? { |x,y| cell(x,y).maru? } @result = MARU_WIN; break # 決着がついて無くて,全部埋まれば引き分け @result = DRAW if @result==NOT_END && filled? return @result != NOT_END 1列全部×? [ [0, 0], [1, 1], [2, 2] ] 1 2 1 2

TickTacToe#end? その4 - all? candidates.each do |candidate| if candidate.all? { |x,y| cell(x,y).batu? } @result = BATU_WIN; return true end if candidate.all? { |x,y| cell(x,y).maru? } @result = MARU_WIN; return true # 決着がついて無くて,全部埋まれば引き分け @result = DRAW if @result==NOT_END && filled? return @result != NOT_END 1列全部×? [ [2, 0], [1, 1], [0, 2] ] 1 2 1 2

TickTacToe#display_result def display_result puts self.to_s # 終局図を表示 puts case @result when BATU_WIN then "x WIN!" when MARU_WIN then "o WIN!" when DRAW then "DRAW" end

TickTacToe – to_s : 文字列化 WAKU = " +-+-+-+\n" def to_s str = "y x:0 1 2 \n" str += WAKU @field.each_with_index do |row, i| str += "#{i} |" + row.join("|") + "|\n" end return str

配列 : join - 連結して文字列化 1 2 join("|") "1|2|3" 3

文字列への式の埋め込み "#{i}: #{i*2}" "%d: %d" % [ i, i*2 ] 変数の埋め込み #{} で囲む シングルクオート ' だと #{} の効果がない "#{i}: #{i*2}" "%d: %d" % [ i, i*2 ]

Player クラス アクセサ定義 一行読み込んで,数値化 class Player attr_accessor :name def initialize( name ) @name = name end def input puts current_player.name + " のターン" print "x> "; x = gets.to_i print "y> "; y = gets.to_i return x, y アクセサ定義 一行読み込んで,数値化

attr_XXXX - syntactic sugar attr_reader 読み取り専用アクセサ - attr_reader :hoge def hoge; @hoge; end attr_write 書き込み専用アクセサ - attr_writer :hoge def hoge=(val); @hoge = val; end attr_accessor 読み書きアクセサ attr_reader + attr_write

Q. CPU を実装するには??

Q. Player と CPU の違いは? 入力するのが,人 か コンピュータ かだけ name などは共通なので 継承して再定義する

A. CPU クラスを作る 継承 class CPU < Player def input # CPU の思考ルーチンを組み込む end 継承 class TickTacToe def initialize @players = [ Player.new('x'), CPU.new('o') ] # ... 後略 ... end

デバッグ

バグがある! 置かれている場所に置けてしまう 盤の内側かどうかをチェックしていない

例外処理 例外が throw されると メソッド呼び出しを逆にたどって rescue されたら逆戻りが終わる

TickTacToe#put def put( x, y ) unless cell( x, y ).free? throw "そこには置けません" end if @current_player_index == 0 set_cell( x, y, Batu.new ) else set_cell( x, y, Maru.new )

エラーの例 def main puts current_player.name + " のターン" def put( x, y ) rescue => e warn e.message retry end def put( x, y ) unless cell( x, y ).free? throw "そこには置けません" end

TickTacToe#main def main puts current_player.name + " のターン" x, y = current_player.input # 入力 put( x, y ) # 置く change_player # プレーヤ交代 rescue => e # 置けなかった warn e.message retry # やり直す end

Q. 範囲外を指定したら? 実際にやってみて下さい

より情報を 得るには?

量と質をこなすことが大事 まずは入門書 文法を押さえる CodeGolf / どう書く.org 練習問題として書いてみる 他人のコードを読んでみる リファレンスマニュアルとの格闘

プログラミング Ruby これが定番っぽい? あんまり良書を知らない 書いて覚えた

Rubyist Magazine 出張版 正しいRubyコードの書き方講座 Web でも読めます Rubyist Magazine でググる ただ、平易ではない

まとめ

まとめ オブジェクト と メッセージング 式 と 評価 ブロック

ご静聴 ありがとう ございました

Enumerable

配列をチェックする/要素を探す A チェック B

配列 : max / min - 最大最小 1 3 2 max 3

配列 : find / detect find do |s| s =~ /py/ end py を含む 文字列を探す “ruby” “python” “perl” “python” py を含む 文字列を探す

配列 : any? / all? - チェック all? do |s| s =~ /^p/ end 全部 p から 始まってるか? “ruby” all? do |s| s =~ /^p/ end false “perl” “python” 全部 p から 始まってるか?

配列 : sort - 並び替え 3 1 2 sort 2 1 3

配列 : sort_by - 条件を指定する sort_by do |i| - i end0 条件を指定して ソートする 1 3 2 2 3

配列 : select / find_all - 抜粋 1 1 select do |i| i % 2 == 1 end 2 3 3 奇数を全て取り出す

Array

配列 : データの追加 a.push n a << n a.insert 1, 3 insert push unshift 2 insert n-2 n-1 push … unshift 3 n a.unshift 1

配列 : unshift - 先頭に追加 1 2 3 n-2 n-1 n … unshift a.unshift 1

配列 : insert - 任意の場所に追加 a.insert 2, 3 1 2 n-2 n-1 n insert … 3

配列 : 範囲外に代入したら? a = [ 1, 2, 3 ] a[3] = 4 1 2 3

配列 : 範囲外に代入したら? a = [ 1, 2, 3 ] a[3] = 4 配列の大きさは 勝手に拡張 1 2 3 4

配列 : データの削除 pop a.pop 1 2 3 n-2 n-1 n … shift a.shift

配列 : pop - 末尾から削除 pop a.pop 1 2 3 n-2 n-1 n …

配列 : shift - 末尾から削除 1 2 3 n-2 n-1 n … shift a.shift

配列 : delete - ものを指定して削除 1 2 "foo" n-2 n-1 n … delete a.delete "foo"

ホワイの(感動的)Rubyガイド 僕にはソリが合いませんでした http://www.aoky.net/articles/why_poignant_guid e_to_ruby/