プログラミング言語/Ruby/言語ダイジェスト
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
[[プログラミング言語/Ruby]]
#contents
* Ruby Language Digest [#xd7d634c]
Ruby は行指向型言語です。つまり、改行が一文の区切りとなり...
文末記号としてセミコロン ';' も使えるのですが、一行に複数...
ない限り必要ありませんし、推奨されてもいません。
class NoVipError < StandardError ; end
↑セミコロンで文を区切る頻出例。中身のない例外クラスの定義。
なお、C言語 と同様に、バックスラッシュを打つことで行を継...
できますし、メソッド呼び出しの引数も複数行にわたって書く...
どこでなにが複数行にわたっての記述が可能か、ということは...
そぐうように決められているので、問題はないでしょう(C や ...
この直感はより鋭くなるでしょう)。
** コメント [#pec5986f]
#行末までコメントだぜ
シェルスクリプトや Perl や Python と同じです。
=begin
RDを書くところ。
=end
このように、「'=begin'」のみの行から「'=end'」のみの行ま...
処理系には無視される。
クラスやメソッドの説明をRD(Ruby Document)形式で書くために...
** 変数 [#q44509e9]
Ruby の変数には型がありません。
「すべてがオブジェクト」である Ruby では、変数はそのオブ...
Rubyの変数には数種類あり、識別子の先頭で書き分けます。
: ローカル変数 | local_variable
普通に英数字・アンダーバーで名前を付けます。
宣言は代入と同時、宣言されていないローカル変数の参照は Na...
起こします。
Ruby のローカル変数の宣言と評価順序はびみょーにかみ合っ...
パースしていく感じで考えて下さい。
: グローバル変数 | $global_variable
危険なアイツ。
'$' を先頭につけます。一度も代入せずに参照すると nil を返...
でも危険です。'$var' と間違って '$val' とタイプしてもエラ...
自分で作った変数だと「'$' が先頭 -> グローバル変数」なの...
: 定数 | Constant
大文字で始めると定数にされます。 const や final のような...
宣言は代入と同時です。宣言されていない定数を参照すると Na...
します。この挙動を返るフックは存在しますが後述します。
Ruby の定数の縛りはちょっとゆるく、定数に再代入(初回の代...
しても現在はエラーではなく警告が出るだけです。
また、Ruby の変数は前述のとおりオブジェクトへの参照なので...
参照です。
CONST_ARRAY = []
CONST_ARRAY.push 'hoge'
なので、オブジェクトの操作はし放題です。オブジェクトの変...
あります。
: インスタンス変数 | @instance_variable
Ruby で「オブジェクトの状態」を表現するもの。
'@' を先頭に付けます。一度も代入せずに参照すると nil を返...
メンバー変数とでも言える機能ですが、オブジェクトの外から...
(リフレクション抜きでは)できません。
通常 setter・getter メソッドを定義します。
: クラス変数 | @@class_variable
名前どおりクラスが持つ変数です。
そのクラスと、そのクラスのオブジェクト両方からアクセスで...
サブクラスに継承されたりします。若干スコープがややこしい...
'@@' を先頭に付けます。一度も代入せずに参照すると NameErr...
します。
** リテラル [#m578e446]
Rubyのリテラル表現は豊富です。以下に代表的なものを挙げま...
*** 数値リテラル (Numeric) [#lbc01b3e]
| 123 | 整数 |
| 4567.89 | 実数 |
| ?a | aの文字コード |
*** 文字列リテラル (String) [#o8ef98d2]
| "double_quote" | 式展開などが解釈されます |
| 'single_quote' | 書いたままになります |
| `back_quote` | コマンドとして実行し、出力を値とします |
`back_quote` 構文の挙動は、実は Kernel#` というすごい名...
実現しています。
式展開とは:
val = 123
puts "put #{val} value"
このコードを実行すると、出力は
put 123 value
となります。式展開が有効なリテラル中で、#{...} で Ruby ...
置いてみると、それを評価した値の文字列表現が展開されま...
「式展開が有効なリテラル」と言いましたが、この機能が有...
文字列に限らず、ヒアドキュメントや正規表現リテラルでも...
*** 配列リテラル (Array) [#jb3c0ac8]
[12, "abc", 123.45, some_method()]
カンマで式を区切って並べて要素を指定します。もちろん一つ...
空の配列を作ることも可能です。
*** ハッシュリテラル (Hash) [#n1c30305]
{ "key" => "value", :KEY => 123 }
「キー => 値」という式のペアを、カンマで区切って指定しま...
要素を指定しないで、空のハッシュテーブルを作ることも可能...
Ruby 1.9.x feature:
{ key1: "value", key2: 123 }
キーが Symbol リテラルの場合、こういった書き方もできま...
*** シンボルリテラル (Symbol) [#g39bb67c]
Symbol オブジェクトは、Ruby の識別子の実体でもあるオブジ...
処理系に作られるものもあれば String#intern メソッドによっ...
あります。
「:ident」のようにリテラルが書けます。「:"*hoge*"」のよう...
Symbol をリテラルで書くにはクォートします。
** ブロック付きメソッド呼び出し [#x961ec60]
メソッドに引数としてオブジェクトを渡すのみならず、処理の...
渡すことができます。
method_name(arg, ...) do |x|
...
end
method_name(arg, ...){|x|
...
}
のように記述すると、method_name 内でこのブロックを呼び出...
出来ます。|...| で囲われた部分は、そのブロックが受け取る...
メソッドの引数のようなものですが、メソッドと違ってブロッ...
ローカル変数を見ることが出来ます。
ざっくりと言ってしまうと、高階関数に渡すための無名関数の...
例えば Lisp だと
(mapcar #'(lambda (x) (* x 10)) '(1 2 3))
; => (10 20 30)
のようなことが、Ruby では
[1, 2, 3].map{|x| x * 10 }
# => [10, 20, 30]
と書けます。
Ruby 1.9.x feature:
ブロック引数の扱いが変わっています。
- 多重代入のような挙動から、メソッド引数のような扱いに...
- 外側の環境に同名のローカル変数があるのに、ブロック引...
使った場合、外側の環境の変数として扱われていたのに対...
ブロックローカルな変数が確保されるようになります。
また、ブロックローカル変数宣言が可能になっています。
method_name(arg, ...){|x; a, b|
...
}
これで a や b も、外側のスコープに気兼ねせずに使える名...
なります。
ブロックを受け取った側では、yield を使ってブロックを関数...
呼び出せます。
def method_name(arg, ...)
...
block_returning_value = yield(val)
...
end
この機能によって、制御構文のようなメソッドが Ruby にはい...
** Rubyの真偽評価 [#sfb10875]
以下に述べる条件分岐などで、Ruby の値(=オブシェクト)がど...
かを説明します。
結論から言うと、Ruby における偽とは false と nil であり、...
オブジェクトは真です。
明示的に真を表す代表的な値に true があります。
これら(true, false, nil)はそれぞれ TrueClass, FalseClass,...
インスタンスです。
** 制御構造 [#u6da8d06]
*** 条件分岐 [#k68afffa]
: if 文, if 修飾子 |
if EXPR then ... end
if EXPR [then]
...
end
... if EXPR
EXPR を評価して真ならば、... を実行する。
複数行に分けて書くならば(改行で区切りが明確なので) then ...
if EXPR1
... # (A)
elsif EXPR2
... # (B)
else
... # (C)
end
EXPR1 を評価して真ならば (A) を実行して終わりますが、そう...
EXPR2 を評価して真ならば (B) を実行します。
こうした elsif 部の条件式も全部偽だった場合、(C) の else ...
0 個以上の elsif 部の後に 0 ~ 1 個の else 部が書けます。
: unless 文, unless 修飾子 |
if に似た文法をとりますが、unless は条件式の評価基準が逆...
... unless EXPR
は、EXPR の評価が偽のときだけ ... を実行しますし、
unless EXPR
... (A)
else
... (B)
end
は、EXPR の評価が真ならば (A) を実行し、そうでなければ (B...
ただ、if における elsif に相当するパートはありません。
** 繰り返し [#d785fa55]
Ruby における繰り返し(ループ)のための文とは、
- while
- until
- for
- イテレータ
です。以下これら総称してただ単にループと呼びます。
: while 文 |
while COND [do]
...
end
COND の評価が真である限り、中の文を実行します。do は省略...
: until 文 |
until COND [do]
...
end
while - until は if - unless の関係に対応し、COND の評価...
中の文を実行します。
: for 文
for IDENT in LIST_EXPR
...
end
Ruby の for 文は C などのものと違い、シェルスクリプトや P...
近いです。
これは、配列のように複数の要素の集合である LIST_EXPR(の評...
その各要素を IDENT という変数に取り出して順次処理していく...
in の後にとるオブジェクトには、each というメソッドがイテ...
実装されている必要があります。
for 文は内部でこのメソッドを呼んでいます。
: イテレータ | 例: Array#each
array = [1, 2, 3, 4, 5]
array.each do |x|
p x #=> 1, 2, 3, 4, 5
end
ブロック付きメソッド呼び出しで、「要素に対しての繰り返し...
実装しています。
loop do
...
end
のように、一見制御構造のようなイテレータから、
1.upto(10) do |x|
p x #=>1, 2, 3, ..., 9, 10
end
のように、用途が特化した便利なイテレータもあります。
元々 Ruby のブロック付きメソッド呼び出し機能は、このよ...
を実装する狙いで、CLU という言語を参考にしたものです。
そうした歴史的経緯から、ちょっと前の文書だと
「ブロック付きメソッド呼び出しのブロック」ぐらいの意味...
言葉が使われていたりします。
: break, next, redo, retry |
ループ内でのフロー制御文です。
: break | 現在のループから脱出します。
: next | 現在のループの、現在の回の残りの文を飛ばして、...
: redo | 現在のループの、現在の回の繰り返しをまた初めか...
: retry | 現在のループを始めからやり直します。
** 例外処理 [#p4e37c64]
begin
... # (A)
rescue ExClass => ex
... # (B)
else
... # (C)
ensure
... # (D)
end
(A) 内で起きた例外を rescue で捕捉します。
捕捉する例外クラス ExClass を指定して、変数 ex で実際に捕...
例外オブジェクトを参照します。
「rescue => ex」、「rescue ExClass」のように両者とも省略...
省略された場合は StandardError が指定されたものとして処理...
rescue 節は、発生した例外のクラスが ExClass、またはそのサ...
例外を捕捉します。
並べた rescue 節がひとつも実行されなかった場合、(C) の el...
そして最後に、例外が起きようが起きまいが、どの rescue 節...
されようがされまいが、必ず締めに実行されるのが (D) の ens...
1 個以上の rescue 節のあとに 0 ~ 1 個の else 節が書けま...
そのあとに 0 ~ 1 個の ensure 節が書けます。
** クラス定義 [#z33d56dc]
せっかくのオブジェクト指向言語ですから、クラスの作り方を...
class ClassName < SuperClass
...
end
「< SuperClass」は名の通り継承するクラスを指定します。省...
Object クラスを継承します。評価すればスーパークラスを返す...
ClassNameは大文字で始める必要があります。定数と同じです(...
なのですが)。
定義したクラスのインスタンスは obj = ClassName.new() のカ...
カタチを見て判るとおり、new は予約語ではなくメソッド名で...
使えます。
生成したクラスを初期化したい場合、C++ や Java でいうコン...
ものを定義します。class ... end 内で定義される initialize...
それです。new は自分の引数を initialize に丸投げします。
クラスと似たようなものにモジュールがあります。
module ModuleName
...
end
モジュールはクラスと違って継承できず、インスタンスも持て...
しかし、include によってそのモジュールで定義した機能を
クラス定義中に取り込むことができます(Mix-In)。
*** メソッド可視性の制御 [#t530a764]
class ClassName
public
... # (A)
private
... # (B)
protected
... # (C)
end
C++ や Java と語彙が一緒なので誤用されていることがたまに...
(A) で定義されたメソッドは public で、どこからでも呼べま...
(B) で定義されたメソッドは private で、そのオブジェクト自...
しか呼べません。
(C) で定義されたメソッドは protected で、private のような...
自分のクラスがそのオブシェクトのクラスと同じ、あるいはサ...
オブシェクトのコンテキストでは public な制御がされます。
Ruby のメソッド呼び出し制御の着眼点は、「レシーバ.メソッ...
呼び出すかどうか、に集約されます。
class Hoge
def initialize
priv # これはOK
self.priv # NoMethodError
end
private
def priv
...
end
end
同じコンテキストですらこうです。
それから、いくら private にしようがリフレクションでどうに...
なので、あてにし過ぎるのは止してください。
*** attr系メソッド -- アクセサ定義 [#pa36a72a]
「変数」の節で
メンバー変数とでも言える機能ですが、オブジェクトの外か...
(リフレクション抜きでは)できません。
通常 setter・getter メソッドを定義します。
と述べました。
さて、その setter と getter ですが、set_member(val), get_...
ネーミングは Ruby では一般的ではありません。
obj.member = 123
obj.member
あたかも属性のように、こう書きたいものです。そして Ruby ...
解釈してくれるからです。
class C
def member
@member
end
def member=(val)
@member = val
end
end
これで、インスタンス変数をメソッドで属性のように扱えます。
定義する際においては他のメソッドとなんら変わりなく、代入...
自分で勝手に書けます。
ただ、そういった独自処理もしないのにいちいち上記のような ...
書くのは煩雑です。なのでこれに等しい処理は
class C
attr_accessor :member
end
で可能です。
: attr_reader | getter を定義
: attr_writer | setter を定義
: attr_accessor | 両方を定義
特別な構文のように見えますが、実はリフレクションを駆使...
まとめた 1 メソッドに過ぎません。
def my_attr_reader(name)
define_method(name){ instance_variable_get("@#{name...
end
def my_attr_writer(name)
define_method("#{name}="){|val| instance_variable_s...
end
最低限、こんな感じで自分でも実装できます。
終了行:
[[プログラミング言語/Ruby]]
#contents
* Ruby Language Digest [#xd7d634c]
Ruby は行指向型言語です。つまり、改行が一文の区切りとなり...
文末記号としてセミコロン ';' も使えるのですが、一行に複数...
ない限り必要ありませんし、推奨されてもいません。
class NoVipError < StandardError ; end
↑セミコロンで文を区切る頻出例。中身のない例外クラスの定義。
なお、C言語 と同様に、バックスラッシュを打つことで行を継...
できますし、メソッド呼び出しの引数も複数行にわたって書く...
どこでなにが複数行にわたっての記述が可能か、ということは...
そぐうように決められているので、問題はないでしょう(C や ...
この直感はより鋭くなるでしょう)。
** コメント [#pec5986f]
#行末までコメントだぜ
シェルスクリプトや Perl や Python と同じです。
=begin
RDを書くところ。
=end
このように、「'=begin'」のみの行から「'=end'」のみの行ま...
処理系には無視される。
クラスやメソッドの説明をRD(Ruby Document)形式で書くために...
** 変数 [#q44509e9]
Ruby の変数には型がありません。
「すべてがオブジェクト」である Ruby では、変数はそのオブ...
Rubyの変数には数種類あり、識別子の先頭で書き分けます。
: ローカル変数 | local_variable
普通に英数字・アンダーバーで名前を付けます。
宣言は代入と同時、宣言されていないローカル変数の参照は Na...
起こします。
Ruby のローカル変数の宣言と評価順序はびみょーにかみ合っ...
パースしていく感じで考えて下さい。
: グローバル変数 | $global_variable
危険なアイツ。
'$' を先頭につけます。一度も代入せずに参照すると nil を返...
でも危険です。'$var' と間違って '$val' とタイプしてもエラ...
自分で作った変数だと「'$' が先頭 -> グローバル変数」なの...
: 定数 | Constant
大文字で始めると定数にされます。 const や final のような...
宣言は代入と同時です。宣言されていない定数を参照すると Na...
します。この挙動を返るフックは存在しますが後述します。
Ruby の定数の縛りはちょっとゆるく、定数に再代入(初回の代...
しても現在はエラーではなく警告が出るだけです。
また、Ruby の変数は前述のとおりオブジェクトへの参照なので...
参照です。
CONST_ARRAY = []
CONST_ARRAY.push 'hoge'
なので、オブジェクトの操作はし放題です。オブジェクトの変...
あります。
: インスタンス変数 | @instance_variable
Ruby で「オブジェクトの状態」を表現するもの。
'@' を先頭に付けます。一度も代入せずに参照すると nil を返...
メンバー変数とでも言える機能ですが、オブジェクトの外から...
(リフレクション抜きでは)できません。
通常 setter・getter メソッドを定義します。
: クラス変数 | @@class_variable
名前どおりクラスが持つ変数です。
そのクラスと、そのクラスのオブジェクト両方からアクセスで...
サブクラスに継承されたりします。若干スコープがややこしい...
'@@' を先頭に付けます。一度も代入せずに参照すると NameErr...
します。
** リテラル [#m578e446]
Rubyのリテラル表現は豊富です。以下に代表的なものを挙げま...
*** 数値リテラル (Numeric) [#lbc01b3e]
| 123 | 整数 |
| 4567.89 | 実数 |
| ?a | aの文字コード |
*** 文字列リテラル (String) [#o8ef98d2]
| "double_quote" | 式展開などが解釈されます |
| 'single_quote' | 書いたままになります |
| `back_quote` | コマンドとして実行し、出力を値とします |
`back_quote` 構文の挙動は、実は Kernel#` というすごい名...
実現しています。
式展開とは:
val = 123
puts "put #{val} value"
このコードを実行すると、出力は
put 123 value
となります。式展開が有効なリテラル中で、#{...} で Ruby ...
置いてみると、それを評価した値の文字列表現が展開されま...
「式展開が有効なリテラル」と言いましたが、この機能が有...
文字列に限らず、ヒアドキュメントや正規表現リテラルでも...
*** 配列リテラル (Array) [#jb3c0ac8]
[12, "abc", 123.45, some_method()]
カンマで式を区切って並べて要素を指定します。もちろん一つ...
空の配列を作ることも可能です。
*** ハッシュリテラル (Hash) [#n1c30305]
{ "key" => "value", :KEY => 123 }
「キー => 値」という式のペアを、カンマで区切って指定しま...
要素を指定しないで、空のハッシュテーブルを作ることも可能...
Ruby 1.9.x feature:
{ key1: "value", key2: 123 }
キーが Symbol リテラルの場合、こういった書き方もできま...
*** シンボルリテラル (Symbol) [#g39bb67c]
Symbol オブジェクトは、Ruby の識別子の実体でもあるオブジ...
処理系に作られるものもあれば String#intern メソッドによっ...
あります。
「:ident」のようにリテラルが書けます。「:"*hoge*"」のよう...
Symbol をリテラルで書くにはクォートします。
** ブロック付きメソッド呼び出し [#x961ec60]
メソッドに引数としてオブジェクトを渡すのみならず、処理の...
渡すことができます。
method_name(arg, ...) do |x|
...
end
method_name(arg, ...){|x|
...
}
のように記述すると、method_name 内でこのブロックを呼び出...
出来ます。|...| で囲われた部分は、そのブロックが受け取る...
メソッドの引数のようなものですが、メソッドと違ってブロッ...
ローカル変数を見ることが出来ます。
ざっくりと言ってしまうと、高階関数に渡すための無名関数の...
例えば Lisp だと
(mapcar #'(lambda (x) (* x 10)) '(1 2 3))
; => (10 20 30)
のようなことが、Ruby では
[1, 2, 3].map{|x| x * 10 }
# => [10, 20, 30]
と書けます。
Ruby 1.9.x feature:
ブロック引数の扱いが変わっています。
- 多重代入のような挙動から、メソッド引数のような扱いに...
- 外側の環境に同名のローカル変数があるのに、ブロック引...
使った場合、外側の環境の変数として扱われていたのに対...
ブロックローカルな変数が確保されるようになります。
また、ブロックローカル変数宣言が可能になっています。
method_name(arg, ...){|x; a, b|
...
}
これで a や b も、外側のスコープに気兼ねせずに使える名...
なります。
ブロックを受け取った側では、yield を使ってブロックを関数...
呼び出せます。
def method_name(arg, ...)
...
block_returning_value = yield(val)
...
end
この機能によって、制御構文のようなメソッドが Ruby にはい...
** Rubyの真偽評価 [#sfb10875]
以下に述べる条件分岐などで、Ruby の値(=オブシェクト)がど...
かを説明します。
結論から言うと、Ruby における偽とは false と nil であり、...
オブジェクトは真です。
明示的に真を表す代表的な値に true があります。
これら(true, false, nil)はそれぞれ TrueClass, FalseClass,...
インスタンスです。
** 制御構造 [#u6da8d06]
*** 条件分岐 [#k68afffa]
: if 文, if 修飾子 |
if EXPR then ... end
if EXPR [then]
...
end
... if EXPR
EXPR を評価して真ならば、... を実行する。
複数行に分けて書くならば(改行で区切りが明確なので) then ...
if EXPR1
... # (A)
elsif EXPR2
... # (B)
else
... # (C)
end
EXPR1 を評価して真ならば (A) を実行して終わりますが、そう...
EXPR2 を評価して真ならば (B) を実行します。
こうした elsif 部の条件式も全部偽だった場合、(C) の else ...
0 個以上の elsif 部の後に 0 ~ 1 個の else 部が書けます。
: unless 文, unless 修飾子 |
if に似た文法をとりますが、unless は条件式の評価基準が逆...
... unless EXPR
は、EXPR の評価が偽のときだけ ... を実行しますし、
unless EXPR
... (A)
else
... (B)
end
は、EXPR の評価が真ならば (A) を実行し、そうでなければ (B...
ただ、if における elsif に相当するパートはありません。
** 繰り返し [#d785fa55]
Ruby における繰り返し(ループ)のための文とは、
- while
- until
- for
- イテレータ
です。以下これら総称してただ単にループと呼びます。
: while 文 |
while COND [do]
...
end
COND の評価が真である限り、中の文を実行します。do は省略...
: until 文 |
until COND [do]
...
end
while - until は if - unless の関係に対応し、COND の評価...
中の文を実行します。
: for 文
for IDENT in LIST_EXPR
...
end
Ruby の for 文は C などのものと違い、シェルスクリプトや P...
近いです。
これは、配列のように複数の要素の集合である LIST_EXPR(の評...
その各要素を IDENT という変数に取り出して順次処理していく...
in の後にとるオブジェクトには、each というメソッドがイテ...
実装されている必要があります。
for 文は内部でこのメソッドを呼んでいます。
: イテレータ | 例: Array#each
array = [1, 2, 3, 4, 5]
array.each do |x|
p x #=> 1, 2, 3, 4, 5
end
ブロック付きメソッド呼び出しで、「要素に対しての繰り返し...
実装しています。
loop do
...
end
のように、一見制御構造のようなイテレータから、
1.upto(10) do |x|
p x #=>1, 2, 3, ..., 9, 10
end
のように、用途が特化した便利なイテレータもあります。
元々 Ruby のブロック付きメソッド呼び出し機能は、このよ...
を実装する狙いで、CLU という言語を参考にしたものです。
そうした歴史的経緯から、ちょっと前の文書だと
「ブロック付きメソッド呼び出しのブロック」ぐらいの意味...
言葉が使われていたりします。
: break, next, redo, retry |
ループ内でのフロー制御文です。
: break | 現在のループから脱出します。
: next | 現在のループの、現在の回の残りの文を飛ばして、...
: redo | 現在のループの、現在の回の繰り返しをまた初めか...
: retry | 現在のループを始めからやり直します。
** 例外処理 [#p4e37c64]
begin
... # (A)
rescue ExClass => ex
... # (B)
else
... # (C)
ensure
... # (D)
end
(A) 内で起きた例外を rescue で捕捉します。
捕捉する例外クラス ExClass を指定して、変数 ex で実際に捕...
例外オブジェクトを参照します。
「rescue => ex」、「rescue ExClass」のように両者とも省略...
省略された場合は StandardError が指定されたものとして処理...
rescue 節は、発生した例外のクラスが ExClass、またはそのサ...
例外を捕捉します。
並べた rescue 節がひとつも実行されなかった場合、(C) の el...
そして最後に、例外が起きようが起きまいが、どの rescue 節...
されようがされまいが、必ず締めに実行されるのが (D) の ens...
1 個以上の rescue 節のあとに 0 ~ 1 個の else 節が書けま...
そのあとに 0 ~ 1 個の ensure 節が書けます。
** クラス定義 [#z33d56dc]
せっかくのオブジェクト指向言語ですから、クラスの作り方を...
class ClassName < SuperClass
...
end
「< SuperClass」は名の通り継承するクラスを指定します。省...
Object クラスを継承します。評価すればスーパークラスを返す...
ClassNameは大文字で始める必要があります。定数と同じです(...
なのですが)。
定義したクラスのインスタンスは obj = ClassName.new() のカ...
カタチを見て判るとおり、new は予約語ではなくメソッド名で...
使えます。
生成したクラスを初期化したい場合、C++ や Java でいうコン...
ものを定義します。class ... end 内で定義される initialize...
それです。new は自分の引数を initialize に丸投げします。
クラスと似たようなものにモジュールがあります。
module ModuleName
...
end
モジュールはクラスと違って継承できず、インスタンスも持て...
しかし、include によってそのモジュールで定義した機能を
クラス定義中に取り込むことができます(Mix-In)。
*** メソッド可視性の制御 [#t530a764]
class ClassName
public
... # (A)
private
... # (B)
protected
... # (C)
end
C++ や Java と語彙が一緒なので誤用されていることがたまに...
(A) で定義されたメソッドは public で、どこからでも呼べま...
(B) で定義されたメソッドは private で、そのオブジェクト自...
しか呼べません。
(C) で定義されたメソッドは protected で、private のような...
自分のクラスがそのオブシェクトのクラスと同じ、あるいはサ...
オブシェクトのコンテキストでは public な制御がされます。
Ruby のメソッド呼び出し制御の着眼点は、「レシーバ.メソッ...
呼び出すかどうか、に集約されます。
class Hoge
def initialize
priv # これはOK
self.priv # NoMethodError
end
private
def priv
...
end
end
同じコンテキストですらこうです。
それから、いくら private にしようがリフレクションでどうに...
なので、あてにし過ぎるのは止してください。
*** attr系メソッド -- アクセサ定義 [#pa36a72a]
「変数」の節で
メンバー変数とでも言える機能ですが、オブジェクトの外か...
(リフレクション抜きでは)できません。
通常 setter・getter メソッドを定義します。
と述べました。
さて、その setter と getter ですが、set_member(val), get_...
ネーミングは Ruby では一般的ではありません。
obj.member = 123
obj.member
あたかも属性のように、こう書きたいものです。そして Ruby ...
解釈してくれるからです。
class C
def member
@member
end
def member=(val)
@member = val
end
end
これで、インスタンス変数をメソッドで属性のように扱えます。
定義する際においては他のメソッドとなんら変わりなく、代入...
自分で勝手に書けます。
ただ、そういった独自処理もしないのにいちいち上記のような ...
書くのは煩雑です。なのでこれに等しい処理は
class C
attr_accessor :member
end
で可能です。
: attr_reader | getter を定義
: attr_writer | setter を定義
: attr_accessor | 両方を定義
特別な構文のように見えますが、実はリフレクションを駆使...
まとめた 1 メソッドに過ぎません。
def my_attr_reader(name)
define_method(name){ instance_variable_get("@#{name...
end
def my_attr_writer(name)
define_method("#{name}="){|val| instance_variable_s...
end
最低限、こんな感じで自分でも実装できます。
ページ名: