ローカル変数

ローカル変数は局所変数とも呼ばれる。
最もスコープの狭い種類の変数。

例:「ruby」「_Ruby」
のように先頭が小文字アルファベットかアンダースコアで始まる必要がある。

ローカル変数は以下の範囲をスコープとしている。

  • ブロック
  • メソッド定義
  • クラス・モジュール定義
  • トップレベル

In [1]:
foo = 'foo is toplevel'

def display_foo
    puts foo # エラーになります
end

puts foo # 表示される
display_foo


foo is toplevel
NameError: undefined local variable or method `foo' for main:Object
(pry):4:in `display_foo'
(pry):8:in `<main>'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:355:in `eval'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:355:in `evaluate_ruby'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:323:in `handle_line'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:243:in `block (2 levels) in eval'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:242:in `catch'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:242:in `block in eval'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:241:in `catch'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:241:in `eval'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/iruby-0.2.2/lib/iruby/backend.rb:64:in `eval'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/iruby-0.2.2/lib/iruby/backend.rb:12:in `eval'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/iruby-0.2.2/lib/iruby/kernel.rb:74:in `execute_request'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/iruby-0.2.2/lib/iruby/kernel.rb:41:in `run'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/iruby-0.2.2/lib/iruby/command.rb:76:in `run_kernel'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/iruby-0.2.2/lib/iruby/command.rb:33:in `run'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/iruby-0.2.2/bin/iruby:5:in `<top (required)>'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/bin/iruby:23:in `load'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/bin/iruby:23:in `<main>'

In [2]:
greeting = "Hello, "
pepole = ['Alice', 'Bob']

pepole.each do |person|
    # personのようなローカル変数は「ブロックローカル変数」と呼ばれる
    puts gretting + person # 文字連結されたものが表示される
end

puts person # 参照できないため、エラーになる


NameError: undefined local variable or method `gretting' for main:Object
(pry):13:in `block in <main>'
(pry):12:in `each'
(pry):12:in `<main>'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:355:in `eval'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:355:in `evaluate_ruby'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:323:in `handle_line'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:243:in `block (2 levels) in eval'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:242:in `catch'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:242:in `block in eval'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:241:in `catch'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:241:in `eval'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/iruby-0.2.2/lib/iruby/backend.rb:64:in `eval'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/iruby-0.2.2/lib/iruby/backend.rb:12:in `eval'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/iruby-0.2.2/lib/iruby/kernel.rb:74:in `execute_request'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/iruby-0.2.2/lib/iruby/kernel.rb:41:in `run'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/iruby-0.2.2/lib/iruby/command.rb:76:in `run_kernel'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/iruby-0.2.2/lib/iruby/command.rb:33:in `run'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/iruby-0.2.2/bin/iruby:5:in `<top (required)>'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/bin/iruby:23:in `load'
/Users/Y_Fujikawa/.rbenv/versions/2.2.0/bin/iruby:23:in `<main>'

グローバル変数

非情に広いスコープを持つ変数。
$から始まる必要がある。

グローバル変数はどこからでも参照・変更することができる。
プログラム全体が大きくなれば読みにくくなるので、必要なければ使うべきではありません。


In [ ]:
$foobar = 'barbaz'
$undefined # 存在しないグローバル変数を参照した場合はnilになる

定数

変化しない値を使う際に定数を用いる。
定数名は大文字アルファベットで始まる必要がある。


In [8]:
TEST_HOGE = 'bar'

puts TEST_HOGE

# Bad : 定数を再定義できるが、やっちゃダメ
TEST_HOGE = 'foo'

puts TEST_HOGE


(pry):37: warning: already initialized constant TEST_HOGE
(pry):34: warning: previous definition of TEST_HOGE was here
bar
(pry):42: warning: already initialized constant TEST_HOGE
(pry):37: warning: previous definition of TEST_HOGE was here
foo

In [9]:
# 定数をメソッドの中で定義することはできない → 文法エラーとなる
def set_foo
    PIYO_PIYO = 'bar'
end

set_foo


SyntaxError: (eval):4: dynamic constant assignment
    PIYO_PIYO = 'bar'
               ^

条件分岐と真偽値

実際にサンプルソースを記述して確認していく。


In [10]:
if true
    puts 'ping'
end

# trueは真を表す擬似変数です。
# trueに対して、falseは偽を表します。


ping

In [14]:
# 条件式には文字列や数値などを与えることもできます。
# Rubyでは falseとnil以外はすべての値を真として扱われる。

str = 'ping'

if str
    puts str
end

str2 = nil

if str2
    puts str2
else
    puts '何も出ませんよ'
end

str3 = 0

if str3
    puts str3
else
    puts '何も出ませんよ2'
end


ping
何も出ませんよ
0

In [15]:
# falseの動作確認
if false
    puts 'hoge'
else
    puts 'piyo'
end


piyo

In [26]:
# Ruby : elsif , Java : else if
n = 2

if n.zero?
    puts '0でした'
elsif n.even?
    puts '偶数でした'
elsif n.odd?
    puts '奇数でした'
else
    puts 'わかりません'
end


偶数でした

In [34]:
# 式について
val = 'Hello'

if true
    'Hello2'
end

val
443

# Q. switch caseはありますか?
# A. あります
m = 'トマト'

case m
when 'トマト'
    puts '野菜'
when 'スイカ'
    puts '野菜2'
when 'いちご'
    puts '野菜3'
else
    puts '果物'
end

a1 = 1
a2 = 1

unless a1 == a2
    puts 'Test'
else
    puts 'Test2'
end


野菜
Test2

クラス

クラスの定義式

class クラス名 end

クラス定義内で定義したメソッドは、そのクラスのインスタンスに対して呼び出せる。 これはインスタンスメソッド、あるいは単純にメソッドと言います。


In [36]:
class MyClass
    def hello
        puts 'Hello'
    end
end

my_object = MyClass.new
my_object.hello


Hello

インスタンス変数

インスタンスの中だけで参照できる変数のこと。 インスタン変数は「@length」のように@から始まる名前で表記する。


In [41]:
class Ruler
    def length=(val)
        @length = val
    end
    
    def length
        @length
    end
end

ruler = Ruler.new

ruler.length = 30
ruler.length

# 「length=」ような名前のメソッドが定義できることは新鮮。
# Rubyではインスタンス変数へ代入を行うメソッド名には末尾にイコールをつけます。
# このようなメソッドの呼び出しには、シンタックスシュガーが用意されており「ruler.length = 30」と代入のように記述できます。
#
# 例:1.+(2) → 1 + 2と同等


Out[41]:
3

In [44]:
# 実際にはattr_accessorを用いる
class Ruler2
    attr_accessor :length2
    
    # length2を参照できるか?
    def hoge_hoge
        puts @length2 + 20
    end
end

ruler2 = Ruler2.new

ruler2.length2 = 20
ruler2.length2

ruler2.hoge_hoge


40