Edited at

Ruby基礎文法


Ruby基礎文法


概要


データを表示する。

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():' 'で囲んだ事同じ意味になる。

    • あんまり使わない。



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";
else if 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!