こちらの記事を読まれる方へ
こちらの記事はドットインストールの「Ruby入門」の個人メモです。
ドットインストール:Ruby入門
Rubyの実行のさせ方→データを出力する命令
- irbというコマンドを使ってそこに命令をかく
- ファイルにRubyの命令を書き込んでそれを実行させていくという方法
print "hello world!" # 終わったあとに改行がない
puts "hello world(puts)" # 改行がある
p "hello world(p)" # データの形式がわかるように表示
行の区切りなのですが、1 行にたくさんの命令を書く場合には
「print “hello world!”; print …」のように「;」で区切れば OK。
「;」は省略されることある。
コメントは#のあと
コメントを複数行かきたければ
=begin
コメント
コメント
=end
で囲む
変数と定数
変数: データにつけるラベル→英小文字から始まる
定数: 変更されないデータにつけるラベル→英大文字から始まる→通例として全部大文字で書くこと
msg = "hello world"
p msg
→”hello world”と出力
ADMIN_EMAIL = "taguchi@gmail.com" #定数は
ADMIN_EMAIL = "hogehoge"
オブジェクト、メソッド、クラス
Rubyで使えるデータには文字列、数値などいろいろなデータ型がある
→そしてすべてオブジェクトである。
オブジェクトとは?
→いろいろ便利な命令が詰まったデータ型である。
→そしてその便利な命令をメソッドという。
→そしてメソッドはクラスで定義されている
クラスとは?
→オブジェクトの設計図のようなもの
→全てのデータは何らかのクラスに属している。
→例えば文字列はStringクラスで定義されている
クラスにどんなメソッドがあるかは、公式サイトから見ることができる
→ドキュメント→コアリファレンス→「Classes」でクラス検索
データ(オブジェクト)
– メソッド(クラスで定義)
文字列 – String Class
p "hello world".length
数値オブジェクトを使おう
扱える数値は、整数値、実数値、分数値もOK
演算するための記号は、
足し算は「+」、
引き算は「-」、
掛け算は「*」、
割り算は「/」、
あまりを出すには「%」、べき乗は「**」
自己代入苦手かも
自己代入って何?
「x = x +5」=「x +=5」→いっしょ
→x=10なら15が出力される
数値もオブジェクト
→メソッドが使える
→Numericというクラスで定義されている
数値オブジェクト
x = 10 # 整数値。「_」を無視するので、桁の大きいのは→100_000_000という感じでもOK
y = 20.5 #実数値
z = 1/3r # Rational(1, 3) #分数値の表現の仕方
# + - * / % **
# p x % 3 # 1
# p x ** 3 # 1000
# p z * 2 # 2/3
# x = x + 5
# x += 5 # 自己代入
# p x # 15
p y.round
文字列オブジェクト
文字列オブジェクト
→シングルクォーテーション
→ダブルクオーテーション
→違いは?
# 文字列オブジェクト
name = "taguchi"
x = "hel\tlo\n world, #{name}" # 変数展開、特殊文字(\n \t)
y = 'hel\tlo\n world, #{name}'
puts x
puts y
# + *
puts "hello world" + " taguchi"
puts "hello " * 5
“hello world” → 変数展開可能、特殊文字使用可能(\n:改行 \t:タブ)
‘hello world’ → できない
文字列の演算
→連結するときは「+」、
→繰り返しをするときは「*」をつかう
破壊的メソッド、真偽値を返すメソッド
破壊的メソッドとは?
→元データをメソッドで命令した形に改ざんするメソッド
例:
s = "taguchi"
puts s.upcase # upcaseは大文字にするというメソッド
→このまま出力すると「TAGUCHI」となる
これを破壊的メソッドにすると
puts s.upcase!となる
puts s.upcase!
puts s
→一度「puts s.upcase!」を行えば
メソッドをつけずに「puts s」とするだけで「TAGUCHI」と出力される
真偽値を返すメソッドとは?
→これは「true」か「false」を返すメソッド。メソッドの最後は?がついている
例えば空文字列かどうかを調べるメソッドに「empty?」がある
s = ""
p s.empty? # true
→これはsが空欄かどうかを問う命令だが、返る答えはtrueである。
配列オブジェクトを使おう
配列とは
→複数のデータをまとめることができるデータ型のことです。
配列には、文字列を入れたり、配列の中に配列を入れることができる。
要素??
→配列の中に入ってるデータ?
配列にはいろいろなデータ型を入れられます。
要素へのアクセスの方法なのですが、「p sales[]」として、大括弧のなんかに添字を書きます。
添字??
→添字は0から始まる数字で、最初の要素は0番目の要素、次の要素が1番目の要素、…のように数えていきます。
書き換えることもできるので、実は8ではなくて10だったという場合には、
例えば「sales[1] = 10」のようにすると配列ないの要素を書き換えれる
添字の指定方法は?
→ピンポイントで指定したい場合→数値(添字の番目)を指定する
→範囲を指定したい場合→「p sales[0..2]」「..」をすると0番目、1番目、2番目を範囲にする。
∟「p sales[0...2]」「…」とすると0から2未満、つまり0番目と1番目が表示される
※「..」は範囲「…」は未満
「p sales[-1]」とすると最後の要素を指定できます。
「p sales[1,2]」とすると、1番目からの要素から2個分取ってくることができる。
配列オブジェクト
sales_1 sales_2 ...
sales = [5, 8, 4]
sales[1] = 10
p sales[1]
p sales[0..2]
p sales[0...2]
p sales[-1]
p sales[1, 2]
配列オブジェクトの続き
添字の指定方法の応用
→複数の要素を一気に書き換えたり、
配列の途中に要素を入れたり、
要素を削除したりできる。
複数の要素を一気に書き換えるのは「=」をつかう
→sales[0...2] = [1,2]→これで0から2未満が1と2にかわる
配列の中に要素をいれるのは「要素を指定する方法を応用」する
→ sales[1,0]→要素の一番目から0個分を指定して
→ sales[1,0] = [10,11,12]→1番目の数字の前に10,11,12が入る。
配列の中の要素を消すときは「空配列」にするという操作をします。
→例えば0番目から2個分を食う配列にしたいときは
→sales[0,2]=[]としてあげると良い。
# 配列オブジェクト
sales = [5, 8, 4]
sales[0...2] = [1,2]
sales[3, 0] = [10, 11, 12]
sales[0, 1] = []
p sales.size
p sales.sort
p sales.sort.reverse
p sales.push(100)
sales << 100 << 102
p sales
p sales.size
p sales.sort.reverse
p sales.push(100)
sales << 100 << 102
p sales
配列でよく使うメソッド
.size→要素数を表示する
.sort→小さい順に並べ替えてくれる
.sort.reverse→大きい順に並べ替えてくれる→.reverseをつかうことで逆順になった
∟メソッドは「.」でつなげていくことができる。
.push→配列の末尾に要素を追加するためのもの
∟ショートカットもある。配列を指定して、「<<」で追加していく。
∟たとえば102と100を追加したければ sales << 100 << 102 としてあげる
配列についてのメソッドはArrayクラスにある。
ハッシュオブジェクトを使おう
ハッシュとは?
→配列と同じように複数の値を管理するもの
配列とは違い、配列が値だけを管理していたのに対して
ハッシュは、識別子であるキーを付けることができます。
数値だけでなく、それが誰の数値かを管理する場合
sales = {"taguchi" => 200,"fkoji" => 300}
のように書く。
taguchiの数値を取り出したいときは
p sales["taguchi"]
とする※200が出力される。
この場合、キーが文字列だった場合は「シンボル」という書き方ができる
sales = {:taguchi => 200, :fkoji => 300}
→:をつかっている。
これでシンボルオブジェクトになる。
シンボル→識別子として使えるオブジェクトのこと。
∟文字列をつかうより動作が速かったりするので書き方として覚えておくとよい
キーがシンボルの場合、こういう書き方もできる
sales = {taguchi:200,fkoji:300}
「{“taguchi” => 200, “fkoji” => 300}」も
「{:taguchi => 200, :fkoji => 300}」も
「{taguchi: 200, fkoji: 300}」もほとんど同じ意味なので、どれも使えたり読めたりするようにしておくのがよいでしょう。
キーを複数取り出すときに
p sales[:taguchi,:fkoji]
ってすればいいの?→できなかった。
メソッド
p sales.size
→要素数を返す
p sales.keys
→キーだけを返す
p sales.values
→バリュー(値)だけを返す
p sales.has_key?(:taguchi)
→そのキーがあるかどうかを真偽値で返す場合
Hashクラスに定義されているのでコアリファレンスを見ると良い。
オブジェクトを変換してみよう。
数値オブジェクトと文字列オブジェクトの足し算
a = 10
b = "5"
p a + b.to_i # 文字列を整数に直す
※.to_i
p a + b.to_f # 文字列を実数に直す
※.to_f
p a.to_s + b # 数値を文字列に直す
※.to_s
ハッシュと配列の相互変換
h = {taguchi: 100, fkoji: 200}
p h.to_a
→ハッシュを配列に直したい場合
→ [:taguchi,100],[:fkoji,200]
→キーと値が配列になって、それを大きな配列で囲っている形に直してくれる。
→:taguchiの「:」って何でつくんやったっけ?
p h.to_a.to_h
→配列に直したものをまたハッシュに直すとき。
→これどんなときに使うん?意味なくない?
%記法を使う
%記法
%記法とは?
→文字列や配列のべつの書き方
s = "hello"
は、
s = %Q(hello)
とかける。なんで「Q」?
※文字列を囲う括弧は記号か文字列の場合なんでも良い
ex:
s = %!hello!
や
s = %{hello}
など
s="hello"
と
s = %Q(hello)
→全部いっしょの意味
→ほんま?
%記法のメリット
→文字列の中で区切り文字を使いたいときは便利
例えば「”…”」の中で「”」を使いたい場合、「”hel”lo”」のように「\」を付けるというルールがある。
%記法だとその「\」を付ける必要がなく、
普通に「%Q(hel”lo)」のように書くことができて便利。
s = "hel\"lo"
s = %Q(hel"lo) # %記法
→バックスラッシュがいらない
ちなみに文字列を「’…’」で囲う方法もありましたが、その場合は「%q(…)」とすればいい。
→「’…’」と「”…”」で変数展開をしたりとかそういった違いがあるから、それに応じて使い分けること
s = 'hel\"lo'
s = %q(hel"lo)
→シングルクォーテーションで囲む場合は「Q」が小文字
ちなみに「$Q(…)」はよく使うので、「Q」を省略して「%(…)」と書けます。
s=%(hello)
→これだけでOK
次は配列
配列の%記法は要素が文字列の場合に使用する。
# a = ["a", "b", "c"]
a = %W(a b c)
→まったく同じ※半角スペースはいると思うたぶん。?
→文字列が配列の場合には「”」をすごくたくさん打たなくてはいけなくなるから、省略できる%記法も覚えておいたほうが良い。
また、区切る記号が「’」だった場合は、「%w(…)」(Wが小文字)となるので覚えておいたほうが良い。
# a = ['a', 'b', 'c']
a = %w(a b c)
ifの条件分岐
条件分岐 if
if 条件
真
else
偽
end
score = 50
if score > 60
puts "OK!"
elsif score > 40
puts "SOSO..."
else
puts "NG!"
end
→scoreの数値が60より大きければOK!、低ければNGを出す,そして
それ以外で40以上(41〜59)ならSOSO…を返す条件分岐
※なんで「elsif」elseではないのか。。。?
比較演算子紹介
何々より大きいは「>」
何々より小さいは「<」
何々以上は「>=」
何々以下は「<=」
何々と等しいは「==」
何々と等しくないは「!=」
のように書くので覚えておきましょう。
それからそれらの条件を組み合わせるための
「&&」(AND)、
「||」(OR)、
「!」(NOT)
というのもあるので、これも覚えておいてください。
例えば score が 40 より大きくて、score が 60 より小さいというのは
「score > 40 && score < 60」と書くことができます。
if文の省略
例えば score が 60 より大きかったら OK と出すときに、後ろで if 文を使うことができます。
puts "OK!" if score > 60
のような形で記載できる。
真偽値と条件演算子
Rubyではオブジェクトが真か偽で評価される
真偽の判断
true: それ以外(0 ” を含む)
※他の言語では「0」「”」(空文字列)も偽になるから注意
false: false nil(オブジェクトが存在しない)の場合
if x # ==trueが省略されている
puts "..."
end
これを見ると、前回見たような比較のための演算子がないじゃないかと思うが、これは「 == true」が省略されている。
Ruby ではオブジェクトそれ自体が真か偽に評価されるので、こういった書き方が可能になっています。
条件演算子
条件演算子というのは何かというと、if-else 文を簡単に書くことができる構文になります。
if-else 文で
if 条件
a = b
else
a = c
end
と書いたりしますが、それを簡単に書く方法があって、それが条件演算子と呼ばれています。
a = 条件 ? b : c
例:「b = 10」「c = 20」で、大きかった方を a に返すという処理
b = 10
c = 20
b, c = 10, 20 # 多重代入→「b = 10 c = 20」と同じ
a = b > c ? b : c
puts a
条件演算子は怪しいかも?
caseで条件分岐
これはあるオブジェクトがあって、それをいくつかの値と比較しながら処理を振り分けていく際に使える構文になります。
=begin
条件分岐 case
case 比較したいオブジェクト
when 値
処理
when 値
処理
when 値
処理
else
処理
end
=end
signal = "blue"
case signal
when "red"
puts "STOP!"
when "green", "blue"
puts "GO!"
when "yellow"
puts "CAUTION!"
else
puts "wrong signal"
end
書く値にマッチした処理がされる。
signalがblueならGOが出力される。
16 times、while、break、nextを使おう
繰り返し処理
→いわゆるループ処理。
timesメッソッド
→一番単純な繰り返しは、数値オブジェクトにtimesメソッド
3.times do
puts "hello"
end
→helloが三回繰り返される
→繰り返す回数を入れると気には、【do】のあとに変数名を入れる
→そうすると「i」がdo…endの中で使えるので、
3.times do |i|
puts "#{i}:hello"
end
→文字列の中に変数を使う場合は「#{変数名}」なの??
→回数を入れるときは「i」限定?他にもあるの?
timesを使うと必ず0からはじまる。
whileメソッド
→while文は次の条件が真の間、次の処理をしなさいというもの。
※いろいろ半角スペース開けるのはみやすくするため??
さっきと同じhelloを三回繰り返すのは
i = 0
while i < 3 do
puts "#{i}:hello"
i += 1
end
とかく。
i<3 となっているのがポイント
→while文は条件が真の間に繰り返すため
ループを抜ける処理がある
→breakとnext
break:ループを抜ける
next:ループを1回スキップする。
例えば
3.times do |i|
if i == 1
break
end
puts "#{i}:hello"
end
1のときにbreakするので、0:helloしか表示されない。
1のときにスキップするのだと
3.times do |i|
if i == 1
next
end
puts "#{i}:hello"
end
とすればよい
0:hello
2:hello
が表示される
for、eachを使おう!
for文
→
0,1,2と繰り返して表示したい場合。
for i in 0..2 do
puts i
end
配列の添え字で見たように、「0..2」というのは 0 から 2 までの範囲の数値を作ってくれるので、それらを 1 つずつ i に入れて表示させているという処理になります。
0..2の部分は配列やハッシュにもできる。
→
配列の場合
for color in ["red","blue","pink"] do
puts color
end
ちなみに配列、ハッシュの場合はfor文よりもeachメソッドの方が良い
["red","blue","pink"].each do |color|
puts color
end
ハッシュの場合
{"red"=>200,"blue"=>100,"pink"=>50}.each do |color,price|
puts "#{color}: #{price}"
end
→ハッシュのときの書き方疑問あるかも。。。?
関数的メソッドを作ってみよう。
関数的メソッド
→オブジェクトに結びついた形でメソッドを呼びだすのではなく。
直接呼び出すメソッドのこと。
メソッドを定義してそれを呼び出す
→定義するには、「def」のあとに関す名を書く
def sayhi
puts "hello"
end
sayhi()
→呼び出すにはメソッド名のあとに「()」を書く
sayhi()
また、メソッドにはオプションを持たせることができる。
def sayhi(name)
daf sayhi(name,place) →複数の場合はカンマ区切りにすること
また、引数には初期値を設定することができる。
def sayhi(name = "Steve")
puts "hello " + name
end
sayhi("Tom")
sayhi("Bob")
sayhi()
→最後の空欄のときはSteveが表示される
その他、メソッドは返り値を持たせてあげることができる
→返り値ってなんぞや?返り値の使い方、、、?
返り値を持つとメソッドの結果を代入することができる
→これが謎?
def sayhi(name = "Steve")
# puts "hello " + name
s = "hello " + name
return s
end
greet = sayhi()
puts greet
→こういった形でかける。
他の演算で使えたりもするというがそれってどういうこと?
メソッドの中で定義された変数は外からアクセスできない。
コードメモ
def sayhi
puts "hello"
end
sayhi()
def sayhi(name)
puts "hello " + name
end
sayhi("Tom")
sayhi("Bob")
def sayhi(name = "Steve")
puts "hello " + name
end
sayhi("Tom")
sayhi("Bob")
sayhi()
def sayhi(name = "Steve")
# puts "hello " + name
s = "hello " + name
return s
end
greet = sayhi()
puts greet
puts s # エラーがでる。メソッド内で定義された変数にはアクセスできないから
クラスを作ってみよう!
クラスとは?
→オブジェクトの設計図
クラスから作られたオブジェクトをインスタンスと呼ぶ
例:Userクラスを作り、その中にsayHIというメソッドを実装する。
class User # クラス名は必ず大文字から
def initialize(name) #initializeという特殊なメソッドを定義→特殊なメソッドって何?
@name = name
end
def sayHi
puts "hello, my name is #{@name}"
end
end
tom = User.new("Tom")
bob = User.new("Bob")
tom.sayHi()
bob.sayHi()
まずはクラスを定義する
→クラス名は必ず大文字から始まる。
特殊なメソッド(initialize)は、クラスからオブジェクト(つまりインスタンス)を創るときに必ず実行される初期化処理のこと→ほんとに?
インスタンスを創るときはだいたい引数が渡される。
→今回はユーザーの名前が渡ってきたと想定します。※initialize(name)
この名前「(name)」を @name という変数にいれる
→@から始まる変数は、インスタンス変数と呼ばれる。
メソッド内で使われた変数は、原則他では使えないが、
このインスタンス変数を使えばそのインスタンス内の別のメソッドから呼び出せる。
インスタンスを創る
→クラス名に「.new」をつけるのが決まり文句
インスタンスを創るとオブジェクトがかえってくる→??
tom = User.new(“Tom”)→tomという変数→これは理解。
クラスメソッド、クラス変数を使おう
→前回の続き
クラスの中でメソッドを定義するとインスタンスから呼び出すことができるインスタンスメソッドになる。
そうではなくて、クラスから直接呼び出すことができるメソッドも定義することができる。
→クラスメソッド
クラス・メソッドを定義するには、クラス名を書いた後にメソッド名を書きます。
def User.sayHello # クラスメソッド
puts "hello from User class"
end
インスタンス変数と同じように、クラス変数というのもある。
クラス変数は先頭に「@@」をつける。
インスタンスの初期化っってなんや?
class User # クラス名は必ず大文字から
@@count = 0 # クラス変数
def initialize(name) #initializeという特殊なメソッドを定義→特殊なメソッドって何?
@name = name # インスタンス変数
@@count += # インスタンスが初期化されるたびに
end
def sayHi # インスタンスメソッド
puts "hello, my name is #{@name}"
end
def User.sayHello # クラスメソッド
puts "hello from User class (#{@@count} users)" # 今何人いるかを表示
end
end
User.sayHello()
tom = User.new("Tom") #インスタンスを創っている。というかこの場合作る必要がある。
bob = User.new("Bob")
tom.sayHi()
bob.sayHi()
User.sayHello()
この部分(クラス・メソッド、クラス変数、インスタンス変数、クラス)については復讐必要。
クラスの継承→クラス(オブジェクトの設計図)の継承
クラスの継承
→Userクラスとほぼ一緒だけどもその性質を受け継ぎつつちょっとちがったクラスを作りたい時に使える。
前回のUserクラスに似たSuperUserというのをつくりたいとき
class User
def initialize(name)
@name = name
end
def sayHi
puts "hello, my name is #{@name}"
end
end
class SuperUser < User # Userクラスの性質を引き継いでいる。
def shout
puts "Hello! from #{@name}"
end
end
tom = User.new("Tom") # tomはUserクラスのみしかつかえない
bob = SuperUser.new("Bob")
tom.sayHi()
bob.sayHi()
bob.shout()
アクセサを使ってみよう!
クラスをインスタンス化してメソッドをつかう
→インスタンス変数にアクセス
→しかしクラスのインスタンス変数は外部からアクセスできない。
そこでアクセスできるようにする方法がある。
→アクセスするためには、アクセスするためのメソッドを別途用意すると良い。
@nameの値を取得するには、インスタンス変数と同じ名前のメソッドを作る必要がある。
→getter
@nameの値を設定するためには、インスタンス変数に新しい値を代入するメソッドを作る必要がある。
→setter
getterとsetterの2つを合わせて、アクセサという。
getterと、setterはまとめてかくことができる。
また、getterのみ、setterのみを生成する命令もある。
class User
def initialize(name)
@name = name
end
=begin
# getter インスタンス変数の値を取得する方法をgetter
def name # 外部からアクセスするために、インスタンスヘンスと同じ名前のメソッドを作る必要あり。
return @name # returnは省略可能。
end
setter インスタンスヘンスの値を設定する方法をsetter
def setName(newName) #値を設定する場合には、インスタンス変数に新しい値を第十する必要がある
@name = newName
end
=end
# 上記、getterとsetterをまとめて書いた処理が下記
attr_accessor :name # getterとsetterを自動生成する命令。シンボルでインスタンス変数の名前を与える。
attr_reader :name # getterのみを生成
attr_writer :name # setterのみを生成
def sayHi
puts "hello, my name is #{@name}"
end
end
bob = User.new('Bob') # なぜシングルクォーテーションなのか?
bob.sayHi()
p bob.name # エラーになる→クラスのインスタンス変数は外部からアクセスできないから
# bob.setName('Tom')
bob.name = 'Tom'
bob.sayHi()
Timeクラスの使い方
現在時刻をとりたい
t = Time.now
p t
→これでOK
あとはメソッドをつかって
p t.year → 年だけ
p t.month → 月だけ
p t.day → 日だけ
その他にある特定の日付のオブジェクトがほしい場合
例えば、2016年の1月12日4時15分10秒の場合
t = Time.new(2016,1,12,4,15,10)
p t
とすれば良い。
この特定の日付のオブジェクトには、四則演算が可能。
例えば最初の日付に10秒プラスしたい場合
t = Time.new(2016,1,12,4,15,10)
p t
t += 10
p t
とすれば良い→自己代入っすね。
こうした日付をフォーマットを変えて出力したい場合
例えば
t = Time.new(2016,1,12,4,15,10)
p t.strftime("今日の日付は:%Y-%m-%d")
これで出力すると
→”今日の日付は:2016-1-12”となる