Ruby基礎文法
概要
- 公式サイト
- 純オブジェクト指向プログラミング言語
- Ruby on Railsで採用されて人気。
データを表示する。
print "hello world!" 終わった後に改行がない
puts "hello world" 改行がある
p "hello world(p)" データの形式がわかるように表示する。
便利なコマンド
-
irb:インタラクティブにRubyを記述できる。exitで抜ける]
-
ri: [知りたい命令とかオブジェクトを見る。 qで抜ける]
長いコメント
ex: コメントアウト
=begin
コメント
コメント
=end
変数と定数の違い。
-
変数:データにつける
- (小文字から始まる)
-
定数:変更されないデータになる。
- (全て大文字となるABCDEGG)
- 大文字から始まれば定数
msg = "Hello world"
p msg
- 定数は上書きできるが警告がでる!
ADMIN_EMAIL ="endo@yahoo.co.jp"
ADMIN_EMAIL ="endo@yahoo.co.jp" //怒られる
Rubyにおけオブジェクト、メソッド、クラス
-
データ(ocject)
:色々な便利な命令が詰まった データ型であると認識する - メソッド(クラスで定義されている。)
- objectの設計図
- 文字列だったら
StringClass
- Rubyでリテラルを使って簡単にオブジェクを作成する事ができる。
したがってRubyはオブジェクトに適するクラスとそのメソッドを書いていくことでプログラマーにとって書いてて気持ちの良い言語であると理解できる。
-
"Hello wold".length
これは文字列オブジェク
.length
と理解する。
"Helloworld"
とは文字列のデータ型であると同時に文字列のオブジェクトでもあると考えられる。
ex:どのクラスに属して、どのメソッドを使えるのかを把握する。
#このobjがどんなクラスに属しているのか
p 4.8.class
#このobjがどんなmethodを使えるのか
8 p 3.8.methods
# result
Float
[:%, :*, :+, :-, :/, :<, :>, :-@, :**, :<=>, :<=, :>=, :==,
:===, :eql?, :inspect, :to_int, :to_s, :to_i, :to_f, :hash,
:coerce, :divmod, :fdiv, :modulo, :abs, :magnitude, :zero?,
:floor, :ceil, :round, :truncate, :positive?, :negative?,
:quo, :nan?, :infinite?, :finite?, :next_float, :prev_float,
:to_r, :numerator, :denominator, :rationalize, :arg, :angle,
:phase, :+@, :singleton_method_added, :div, :i, :remainder,
:real?, :integer?, :nonzero?, :step, :rectangular, :rect,
:polar, :real, :imaginary, :imag, :abs2, :conjugate, :conj,
:to_c, :between?, :instance_of?, :public_send,
:instance_variable_get, :instance_variable_set,
:instance_variable_defined?, :remove_instance_variable,
:private_methods, :kind_of?, :instance_variables, :tap,
:singleton_method, :is_a?, :define_singleton_method,
:extend, :method, :public_method, :to_enum, :enum_for, :=~,
:!~, :respond_to?, :freeze, :display, :object_id, :send,
:nil?, :class, :singleton_class, :clone, :dup, :itself,
:taint, :tainted?, :untaint, :untrust, :trust, :untrusted?,
:methods, :protected_methods, :frozen?, :public_methods,
:singleton_methods, :!, :!=, :__send__, :equal?,
:instance_eval, :instance_exec, :__id__]
数値記号
-
-
-
- / % **
-
-
ex:基本演算記号
p x%3 #1
p x**3 #1000
p z*2 #2/3
Float型
- 整数も浮動小数もオブジェクトなので便利なメソッドを使える。
ex:Floa型
#Floatクラス
#5分の2
puts Rational(2,5)
puts 2/5r
#p y.round(四捨五入)
p 52.6.round#四捨五入
p 52.6.floor#小数点以下切り捨て
p 52.6.ceil #小数点以上、切り上げ
自己代入!
ex:自己代入
x= x+5
x += 5
文字列オブジェクト
-
""で囲む文字列object
- 変数展開,特殊文字が浸かる
- ''で囲む文字列object
- 変数展開はできない。
-
#{}
で変数の中身が評価される。
ex:文字列オブジェクト
price = 1400
# #{}はさむ事で式が評価される
puts "price #{3000*4}" #ちゃんと評価される
puts "price {3000*4}" #評価されない
puts 'price #{3000*4}'#そもそも''だから、変数が評価されず展開されない。
name="Endo Futoshi"
puts " Hello My nama is #{name}!"
#文字列でよく使うオブジェクトメソッド
puts "hello "+"wold"
puts "hello "*3
# result
price 12000
price {3000*4}
price #{3000*4}
Hello My nama is Endo Futoshi!
hello wold
hello hello hello
破壊的メソッド(!),真偽値を返すメソッド(?)
- ! 破壊的メソッド
-
upcase
文字列を大きくして返す。 -
upcase!
文字列を大きくして、元の文字列も書き換える。
-
ex:破壊的メソッド
#! 破壊的メソッド
name="endo"
puts name.upcase
puts name
#破壊的メソッドが実行された。
puts name.upcase!
#元の値自体が変わってしまった。
puts name
# result
ENDO
endo
ENDO
ENDO
-
真偽値を返すメソッド
-
?:真偽値を返すメソッド
- true,false で結果を返す。
ex:真偽値を返すメソッド
# ?真偽値オブジェクト
p name.empty? #返却値はtrue か false 今回はFalse
p name.include?("e") #false なぜなら破壊されているから
p name.include?("E")
# result
false
false
true
配列オブジェクト
ex: 配列オブジェクト
colors = ["red","blue","Yellow"]
p colors[0]
p colors[-1] #末尾
# result
"red"
"Yellow"
配列の範囲指定
ex:配列での範囲してい。
p sales[0..2] # 0 1 2 (0~2以上)
p sales[0...2] #0 1のみ (0~2未満)
numbers = [1,2,3,4,5,6,7,8,9,10]
p numbers[0..2]
p numbers[0...2]
p numbers[10] # nil
# result
[1, 2, 3]
[1, 2]
nil
末尾の要素を指定する
ex:末尾の要素を指定する。
colors = ["red","blue","Yellow"]
p sales[-1]
# result
"Yellow"
置き換える
ex:値の置き換える
sales = [5,8,4]
#//置き換え #0から2未満(0,1)
sales[0...2] = [1,2]
p sales
#rsult
[1,2,4]
追加する
ex:配列オブジェクト[0,1,3]に[10,11,12]を入れる。
#添字の1から0個分=sales[1]の部分から[10,11,12]を追加する。
numbers = [1,2,3]
p numbers
#要素を追加する。
numbers[1,0] = [10,11,12]
p numbers
# result
[1, 2, 3]
[1, 10, 11, 12, 2, 3]
配列オブジェクトの中に配列オブジェクトを埋め込む
ex:配列オブジェクト[0,1,3]に配列オブジェクト[10,11,12]を入れる。
numbers = [1,2,3]
p numbers
#配列オブジェクト自体を追加する。
numbers[1.0] = [10,11,12]
p numbers
# result
[1, 2, 3]
[1, [10, 11, 12], 3]
削除する。
ex:要素を消去する。
#sales[0,2]=[] #0から2未満なのでsalse[0],sales[1]が空になる。
numbers = [1,2,3]
p numbers
#要素を消去する。
numbers[0,2] = [ ]
p numbers
# result
[1, 2, 3]
[3] # 1,2が消える。
配列オブジェクトで使えるメソッド
ex:配列オブジェクトで使えるメソッド
- size:要素数
- sort:ソートする。
- reverse:逆にする。(sort.revrseで逆順にソートする。)
p sales .size #要素の数
p sales.sort #ソートする。
p sales.sort.reverse #メソッドはピリオドでつなげていく
pushメソッド
- push:配列の末尾に要素を付け加える
ex:pushメソッド
animals = ["dog","cat","mous"]
p animals
animals.push("pig")
p animals
# result
["dog", "cat", "mous"]
["dog", "cat", "mous", "pig"]
hashオブジェクト
改めて配列とハッシュの違いを確認しておくと、配列は複数のオブジェクトを順に並べて先頭から番号を割り当てたものです。それに対して**ハッシュはバラバラの位置に配置したオブジェクトに目印となるキーが付いていると考えて下さい。ハッシュでは要素の順番というものがありませんので、何番目の要素という形式では参照できません。**対応するキーを指定することで値を取得します。
#ハッシュオブジェクトを創る (キーが文字列)
scores_1={"endo"=>200,"takahasihi"=>400}
#シンボル名で書く(動作が高速である)
scores_2={:taguchi =>200,:watanabe => 150}
#シンボル名は以下の様に短くできるし、読みやすい。
scores_3={iida: 200,saeki: 320}
ex1:hashObj
sales ={"taguch":200,"endo":400,"tanaka":300}
p sales
p sales[:endo]
ex2:hashObj キーがシンボルオブジェクト(識別子)
sales = {:taguchi =>200,:endo=>400,:tanaka=>300}
p sales
p sales[:endo]
ex3:シンボルオブジェクトの省略形。
sales = {taguchi: 200,endo: 400,tanaka :300}
p sales
p sales[:endo]
# resultは全て同じ
{:taguch=>200, :endo=>400, :tanaka=>300}
400
hashオブジェクトで使えるメソッド
- p sales.size :要素数
- p sales.key :キー
- p sales.value :値
- p sales.has_key?(:endo) :
:endo
(キー)と紐付いた値はあるのか?
ex:HashObj
scores_3={iida: 200,saeki: 320}
p scores_3[:iida]
p scores_3[:saeki]
scores_3[:iida]=600
scores_3[:iida]
p scores_3.size
p scores_3.keys
p scores_3.values #中に値があるか確認する。
p scores_3.has_key?(:iida)
# result
200
320
2
[:iida, :saeki]
[600, 320]
true
オブジェクトを相互に変換する。
ex:数値Objと文字列Objをそのまま変換しようとするとエラーになる例。
a=10
b="5"
p a+b`
#result
#Errorが起きる
文字列を数字として扱う。
- to_i:int型に変換する。
- to_f:float(浮動小数型)に変換する。
ex:intとfloatの変換
a=10
b="10"
if a == b.to_i
puts "true"
else
puts "false"
end
# result
True
ex2:文字列と数値型を総合変換する。
a=10 #数値
b="5" #文字列
p a+b.to_i
p a+b.to_f
# result
#15 (整数)(int)
#15.0 (実数)(float)
数字を文字列として扱いたい
- to_s:文字列型に変換する。
ex:数値型と文字列型の相互変換
a=10 #数値
b="5" #文字列
p a.to_s+b #105
HashとArrayを相互変換する
- to_a:Arrayに変換する。
- to_h:Hashに変換する。
ex:Hash→Array
score = {taguchi:200, endo:300}
puts score
puts score.class
# Convert to Arrau
puts score.to_a
puts score.class
# result
{:taguchi=>200, :endo=>300}
Hash
taguchi
200
endo
300
Array
ex2:Array->Hash
score = [[:taguchi,200], [:endo,300]]
puts score
puts score.class
#配列として表示させられる。
puts score.to_h
puts score.to_h.class
# result
taguchi
200
endo
300
Array
{:taguchi=>200, :endo=>300}
Hash
ex3:HashとArrayの相互変換
h={taguchi: 100,Endo: 200}
#(to Array)
p h.to_a
#(to Hasj)
p h.to_a.to_h
# result
[[:taguchi, 100], [:Endo, 200]]
{:taguchi=>100, :Endo=>200}
%記法
参考
- %記法は""や''などの特殊文字を表したいときに使う。
-
%Q():
" "
で囲んだ事同じ意味になる。 -
%q():
' '
で囲んだ事同じ意味になる。 - あんまり使わない。
-
%Q():
ex:%q,%Qを使った例。
name="endo"
puts "hello#{name} !"+"なますて"
puts %Q(hello#{name}!)+%Q(なますて)
puts 'hell #{name}'
puts %q(hello #{name})
# result
helloendo !なますて
helloendo!なますて
hell #{name}
hello #{name}
ex2:特殊文字を表示する。
puts "\"\"は文字列ですが特殊文字を評価します"
puts %Q(""は文字列ですが特殊文字を評価します)
# result
""は文字列ですが特殊文字を評価します
""は文字列ですが特殊文字を評価します
%配列(Array)記法
- %w(小文字) 配列を作る。配列の要素はスペース区切りで指定する。式の展開はされない。
- %W(大文字) 配列を作る。%w()と違い、式が展開がされる。
ex1:%wを使った例。
a=["a","b","c"]
p a
b=%w(a b c)
p b
# result
["a", "b", "c"]
["a", "b", "c"]
ex2:%Wを使った例。
#変数
apple='red'
banana='yellow'
array=%W(#{apple} #{banana} PHP)
p array
# result
["red", "yellow", "PHP"]
書式付きで文字列に値を埋め込む
- %S:文字列
- %d:整数
- $f浮動小数点
この文法を使う時のメリットとしては、文字の幅や小数点2桁切り捨てなどと言った事が出来る点である。
p "name: %s" % "taguchi"
#10桁分の幅を開ける
p "name: %10s" % "taguchi"
#10桁を幅を空けつつ左寄せ(-を入れる)にする。
p"name: %-10s" % "taguchi"
#10.3fは小数点前が10桁、小数点以下が3桁という意味
#05dは5桁にしたいが、5桁にみたない場合は0を入れてくれという意味
p "id: %05d, rate: %10.3f:" %[355,3.84]
#これが2fだから小数点以下は2桁となる。
p "id: %05d, rate: %10.2f:" %[355,3.84]
# printf 書式付きで文字列を表示できる。
# sprintf 文字列を返すだけ
printf("name: %10s \n","endo")
printf("id:%05d, rate:%10.2f \n",355,3.284)
#文字列を返す。
p sprintf("id:%05d, rate:%10.2f \n",355,3.284)
# result
"name: taguchi"
"name: taguchi"
"name: taguchi "
"id: 00355, rate: 3.840:"
"id: 00355, rate: 3.84:"
name: endo
id:00355, rate: 3.28
"id:00355, rate: 3.28 \n"
if文の条件分岐
最期は必ずendを入れる。
基本形
if 条件
真
else
偽
end
elsif
score = 80
if score > 60
puts "ok"
elsif score >40
puts "SOSO"
else
pus "NG!"
1行でif文。
ex:if文を1行で書く。
score = 100
puts "OK" if score >60
# result
OK!
真偽値と条件演算子
Rubyの条件式の判定は以下の通りである。
結果 | 条件 |
---|---|
真 | trueとnil 以外のオブジェクト(0,""を含む))全て |
偽 | falseとnil(オブジェクトが存在しない) |
三項演算子
三項演算子(条件演算子)を使用することによって
if 条件
a=b(式1)
else
a=c(式2)
end
このようなif文を
条件 ? 式1 : 式2
a=条件 ? b : c
と記述する事ができる。
ex:三項演算子
a=10
b=20
a=b>c?:b:c
puts a
# result
20
多重代入
基本例
foo, bar = [1, 2] # foo = 1; bar = 2
foo, bar = 1, 2 # foo = 1; bar = 2
foo, bar = 1 # foo = 1; bar = nil
foo, bar, baz = 1, 2 # foo = 1; bar = 2; baz = nil
foo, bar = 1, 2, 3 # foo = 1; bar = 2
#Array
foo = 1, 2, 3 # foo = [1, 2, 3]
*foo = 1, 2, 3 # foo = [1, 2, 3]
foo,*bar = 1, 2, 3 # foo = 1; bar = [2, 3]
ex:多重代入
#右辺が , 区切りで複数ある場合には配列に変換される
a=1,2,3,4
#左辺も , 区切りで複数ある場合には配列に変換された上で、左辺の各変数に右辺の各要素が代入される
b,c="apple","banana"
p a
p b
p c
#result
[1, 2, 3, 4]
"apple"
"banana"
参考資料
case文で条件分岐
ex:case文
# case分chomp
#chomp:最後の改行コードを取り除く。
#CLから値を受け取る。
signal=gets.chomp
case signal
when "red" then
puts "stop!"
when "green","blue" then
puts "go!"
when "yellow" then
puts "caution!"
else
puts "wrong signal!"
end #最後はendで占める
# result
[vagrant@localhost RubyStudy_2.3.0]ruby case.rb
red
stop!
[vagrant@localhost RubyStudy_2.3.0]ruby case.rb
bllue
wrong signal!
[vagrant@localhost RubyStudy_2.3.0]ruby case.rb
blue
go!
繰り返し処理。
timeメソッド
「times」メソッドは、変数に「0」から「対象のオブジェクトが持つ数値 - 1」を順に代入しながら「{」から「}」までの処理(又は「do」から「end」までの処理)を実行します*1回繰り返す毎に1ずつ数値は増加します。(「|変数|」の部分は省略可能です)。
基本形
オブジェクト.times do |変数|
実行する処理1
実行する処理2
end
ex:FizzBuzz
#FizzBuzz問題
i=0
#0から30まで繰り返す
31.times do |i|
if (i%15==0 && i!=0)
puts "FizzBuzz!"
elsif(i%3==0 && i!=0)
puts "Fizz!"
elsif(i%5==0 && i!=0)
puts "Buzz!"
else
puts "#{i}"
end
end
# result
0
1
2
Fizz!
4
Buzz!
Fizz!
7
8
Fizz!
Buzz!
11
Fizz!
13
14
FizzBuzz!
16
17
Fizz!
19
Buzz!
Fizz!
22
23
Fizz!
Buzz!
26
Fizz!
28
29
FizzBuzz!
参考資料
1行でtimesメソッドを書く
- timesを使うと必ず0から始まるので、そこだけ注意する。
ex:1行times
j=0
10.times{ |j| puts "#{j}:hello" }
#result
0:hello
1:hello
2:hello
3:hello
4:hello
5:hello
6:hello
7:hello
8:hello
9:hello
while文
i=0
while i < 3 do
puts "#{i} hello"
#i =i+1
i +=1
end
break文
- break:roopを抜けます
- nexe:ループを1回スキップ
ex1:1の時にループを抜ける
3.times do |i|
if i == 1
break
end
puts "#{i}: hello"
end
ex2:1の時にnextでスキップする。
3.times do |i|
if i == 1
next
end
puts "#{i}: hello"
end
for文
基本形
for 変数 in 配列オブジェクト do
実行する処理1
実行する処理2
end
ex:for文によるくり返し。
#for
#inにはobjectが入る
#..は"18から20まで"を表わす:(18~20)
for i in 18..20 do #doは省略できる
p i
end
#...は"18から20以下"を表わす:(18~19)
for i in 18...20 do
p i
end
# result
#"18..20は"15から20まで"を表わす"
18
19
20
#"18...20は"15から20以下"を表わす"
18
19
配列オブジェクトをforを回す。
配列オブジェクトの要素数だけ回してくれる。
for color in ["red""blue"]
p color
end
# result
red blue
hashオブジェクトでforを回す。
hashオブジェクトの中身を全て取り出すして表示シてくれる。
for name,score in {"taguchi":200,"endo":400}
puts "#{name}:#{score}"
end
# result
taguchi:200
endo:400
eachメソッド
基本
配列オブジェクト.each |i|
実行する処理1
実行する処理2
end
Arrayクラスにも「each」メソッドは用意されています。配列オブジェクトに対して「each」メソッドを実行すると、配列に含まれる要素を順に取り出して繰り返し処理が行われます。(eachメソッドについてはeachメソッドを参照して下さい)。
「for」文では繰り返しが1回行われるたびにオブジェクトに対して「each」メソッドが実行し取得した要素などを変数に代入します。
for文と違い
- forではループ構文の内外で変数のスコープは変わらない!
- eachではブロックの内外でスコープが変わる!
- each文の方がスコープが狭くて安心だ。
ex1:for文とeachメソッド
colors =["red","blue","yellow"]
## ここのcolorsはどこからでもアクセスできる。
for color in colors
p "color:#{color}"
end
# ## ここのcはeachメソッド内でしか使えない。
colors.each do |c|
p "color:#{c}"
end
#result
"color:red"
"color:blue"
"color:yellow"
"color:red"
"color:blue"
"color:yellow"
範囲オブジェクト(Range)をeachメソッドで処理する。
範囲オブジェクトは実際にはRangeクラスのオブジェクトです。「..」演算子や「...」演算子によって範囲オブジェクトを作成できますが、Rangeクラスのクラスメソッドである「new」メソッドでも作成できます。
(18..20).each |i|
p i
end
# result
18
19
20
配列オブジェクトをeachメソッドで処理する。
["red","blue"].each do |color|
p color
end
# result
"red"
"blue"
Hashオブジェクトにeachメソッドで処理する。
{taguchi:200,end:400}.each do |name,score|
puts "#{name}: #{score}"
end
# result
taguchi: 200
end: 400
参考資料
メソッド。
- メソッドは最後位評価された値をそのまま返す。
- メソッド内で定義されや変数には外からアクセスできないというルールがあるので注意する。
基本構文
ex:sayHiメソッド
#引数は,区切りで複数与えられる
def sayHi(name)
puts "#{name} hi!"
end
sayHi("endo")
#result
endo hi!
デフォルト値の設定
ex:メソッド内にデフォルト値を入れる。
def sayHo(name="endo")
puts "#{name} ho yo!"
end
sayHo("takahashi")
sayHo
#result
takahashi ho yo!
endo ho yo!
クラス
- クラス名は必ず最初の文字は大文字。
- インスタンス生成時に呼ばれるメソッドは
def initialize
と定義する。この時にクラス外から渡される値をインスタンス内で使うようにするためにインスタンス変数を作る(@インスタンス変数)
ex:クラス
class User
#インスタンス時に呼ばれる処理
def initialize(name) #仮引数に"endo"を入れる
#インスタンス変数(インスタンス内で保持する事ができる。)
@name =name
end
#@nameはこのインスタンスはクラス内ではどこでも利用できる。
def sayHi
puts "Hi! i am #{@name}"
end
end
#インスタンスを生成する。
#tomはインスタンスオブジェクトです。
tom= User.new("tom")
tom.sayHi
endo= User.new("endo")
endo.sayHi
# result
Hi! i am tom
Hi! i am endo
アクセサメソッド。
- インスタンス変数にクラス外からアクセスする為のメソッドです。
- アクセサメソッド(ゲッター+セッター)
- attr_accessorで呼び出すことができます。
ex:アクセサメソッド
class Book
#アクセサメソッド(getter+setter)
attr_accessor :title,:price
def initialize(title,price)
#@の名前は一致させる
@title=title
@price=price
end
def sayPrice
puts "Price is #{@price}"
#selfオブジェクト=そのメソッドを受け取っているインスタンス自身を指します。この場合だとbook.sayPrice(レシーバ)が相当する。
puts "price is #{self.price}"
#self演算子は以下の様に省略可能。
#puts "price is #{price}"
end
end
book = Book.new("EndoBook",2389)#インスタンス生成
puts book.title
puts "#{book.price}円"
book.sayPrice #
#インスタンス変数の名前を変えずに値を変えたい時にアクセッサが便利
book.title="TakahashiBooks"
book.price=2050
puts book.title
book.sayPrice
#別の名前にしたい
book_bob=Book.new("BobBobAdventure",1980)
puts book_bob.title
puts book_bob.price
book_bob.sayPrice
#インスタンス変数bookのタイトル名はこれで固定された
puts book.title
#result
#最初のインスタンス精製
EndoBook
2389円
Price is 2389
#アクセサを使って最初のインスタンス変数名を変えずにpriceとtitleを変える。
TakahashiBooks
Price is 2050
#インスタンス2回目
BobBobAdventure
1980
Price is 1980
TakahashiBooks
クラスメソッド、クラス変数。
- クラスメソッド=クラスから直接呼び出せるメソッド(インスタンス変数を呼び出さなくて良い。)
- クラス定数=(一文字が大文字)個々のインスタンスではなくインスタンス全てで値を共有することができます。
-
@@name
:クラス変数
ex:
class User
#@@がクラス変数
@@count = 0 #初期化
def initialize(name)
@@count += 1
@name = name
end
def sayHi
puts "Hi! i am #{@name}"
end
#クラスメソッド①
def self.sayHo
puts "Say Ho!"
puts "Count is #{@@count} insyatance"
end
#クラスで定数①
VERSION = "これはクラス定数です。" #これもクラス外からアクセスできる。
end
#インスタンスを使わずにメソッドを呼び出します。
tom = User.new("tom")
bob = User.new("bob")
steave = User.new("Steave")
#クラスメソッド呼び出し
User.sayHo
#クラス定数呼び出し
puts User::VERSION
# result
Say Ho!
Count is 3 insyatance
これはクラス定数です。
継承クラス
- 継承クラスは子クラスとも呼ばれ、親クラスのメソッド、変数を宣言なしに使えます(継承する。)
- また、親クラスのメソッドの上書きも可能であり、その際にはOverrideされる為、継承クラスのインスタンス時には子クラス内でoverrideされたメソッドが優先される。
- 親クラス < 子クラス:これで継承する。
ex:継承クラスの基本構文。
#継承クラスについて
class User
def initialize(name)
@name = name
end
def sayHi
puts "Hi! i am #{@name}"
end
end
#User:親クラス,SuperClass
#AdminUser:子クラス,SubClass
#継承クラスは親クラスのメソッドや変数を使える。
#子やクラス
class AdminUser < User
def sayHo
#親クラスの変数をそのまま使える。
puts "ho! from #{@name}"
end
#親クラスのメソッドの上書きをするOverride
def sayHi
puts "Hi! Yo! "
end
end
#あくまでここで呼び出しているのは子クラス(継承のみ)
#従って優先されるのは継承クラスでoverrideされたメソッドのみ
tom =AdminUser.new("tom")
tom.sayHi
tom.sayHo
#result
Hi! Yo!
ho! from tom
アクセス権。
- public どこからでも
- private:レシーバを指定できない。 子クラスまでは使える。
- protected 外部から隠ぺいしたい
つまり,privateは自分からしか見えないメソッドであるのに対し
て,protectedは一般の人からは見られたくないが,仲間(クラスが
同じオブジェクト)からは見えるメソッドです。protectedは例えば2項演算子の実装にもう一方のオブジェクトの状態を知る必要があるか調べる必要があるが,そのメソッドをpublicにして,広く公開するのは避けたいというような時に使います.
- 例外として、new したときに呼ばれる initialize メソッドと、クラスの外に書いたメソッドは自動的に private になるので、覚えておきましょう
- Ruby の private 指定は他の言語のオブジェクト指向プログラミングと動作が異なっていて、Sub Class から呼び出せたり、オーバーライドすることができたりするので、十分注意して使う
ex:
class User
def sayHi
puts "hi1"
puts "ここは親クラス内のメソッドです!"
sayPrivate
#意味的には self.sayPrivate なのですが、privateではレシーバーを指定できないので必ず self は省略してあげてsayPrivate のように書いてあげてください。
end
private#クラス内ならば使える
def sayPrivate
puts "これはプライドメソッドです。"
end
end
##クラスが継承されるのでprivateメソッドは子クラス内で呼び出すことが可能。
class AdminUser < User
def sayHo
puts "hello!これは継承クラス内のメソッドです!"
sayPrivate #privateメソッド
end
#なおかつ同名のメソッドの上書きも可能となる。
def sayPrivate
puts "privateメソッドをOverrideした"
puts "private from Admnin"
end
end
#User.new.sayPrivace NG privareアクセス権かかっているので
User.new.sayHi #こここで始めてprivateメソッドが呼ばれる。
AdminUser.new.sayHo
#over rideの呼び出し
AdminUser.new.sayPrivate
# result
hi1
ここは親クラス内のメソッドです!
これはプライドメソッドです。
hello!これは継承クラス内のメソッドです!
privateメソッドをOverrideした
private from Admnin
privateメソッドをOverrideした
private from Admnin
モジュールで名前空間を使う。
- 同じメソッド名が同じファイル内に重複されると、衝突がおきる。
- 従ってモジュールを使って自分だけの名前空間を作ってあげれば衝突を回避する事ができる。
=begin
def movie_encode
end
def movie_export
end
これらのメソッド名は他の人も使って衝突が起きやすくなる。
=end
ex基礎構文
module Movie
VERSION = 1.1
#クラスメソッドの様に書けばいい
def self.encode
puts "encodeing.."
end
def self.export
puts "exporting.."
end
end
Movie.encode
Movie.export
puts Movie::VERSION
#別のモジュールを作る(名前空間的な)
module Movie2
VERSION = 1.1
#クラスメソッドの様に書けばいい
def self.encode
puts "encodeing.."
end
def self.export
puts "exporting.."
end
end
Movie2.encode
Movie2.export
puts Movie2::VERSION
# esult
encodeing..
exporting..
1.1
encodeing..
exporting..
1.1
ミックスイン(モジュールの応用)
- ミックスインに関してはもっと複雑なこともできるのですが、継承関係にない複数のクラスに共通の機能を提供する場合に便利なので慣れておくといいかと思います。
- ミックスインのメインの機能として継承関係にない複数のクラスに共通の機能を提供する場合に便利である
ex:ミックスイン
module Debug
def info
puts "#{self.class} debug"
end
end
class Player
#ミックスイン
include Debug
end
class Monster
#ミックイン
include Debug
end
Player.new.info
Monster.new.info
result
Player debug
Monster debug
例外処理
ex:例外処理
x=gets.to_i
#自分で例外クラスを作る
class MyError < StandardError end
#p 100/x #0を入れるとErrorが発生します。
#例外処理の書き方
begin
if x == 3
raise MyError #自分が作った例外処理を発生させる
end
p 100/x
#例外クラスで発生したオブジェクトMyErrorを作る。
rescue MyError
puts "noy 3!"#独自のメッセージを作る
rescue => ex #発生した例外をexに入れる。
p "エラメッセージ"+"#{ex.message}" #予めた用意されたメッセージを表示する
p "エラー起こしたクラス"+"#{ex.class}" #このオブジェクト名のクラス名
puts "例外が"+"発生しましたよ!"
puts "stopped!"
ensure#例外が発生しよがしまいが、最後に絶対実行したい処理
puts " __END__"
end
# resultの検証
0を入力した時
0
"エラメッセージdivided by 0"
"エラー起こしたクラスZeroDivisionError"
例外が発生しましたよ!
stopped!
__END__
3を入力した時
3
noy 3!