第六回



# variable

今回は変数とメソッドについて取り扱っていきます


# Theme

受け取った引数ARGV[0]をnameという変数に代入してそれを打ち出すプログラムを作る．

    > ruby name_variable.rb Ruby
    Ruby


# 解説

　rubyにおける変数はC言語のように型宣言する必要がないので，以下のように記入すればよい．

```ruby
name='Ruby'
```


# 変数の種類

Rubyには，以下のように様々な変数が存在します．

・ローカル変数・定数・グローバル変数・ブロック変数・インスタンス変数・クラス変数・クラスインスタンス変数


# ローカル変数　　　

　解説に載っていた変数です．一番よくつかわれます．


## 宣言

変数名には英数字と\_(アンダーバー)を使うことができます．先頭には数字を使うことはできず，宣言と初期化を同時に行う必要があります．

```ruby
name="Ruby"    #ok
name_1="Ruby"  #ok

2_name="Ruby"  #NG  ->SyntaxError

name           #NG ->NameError
```


## スコープ　

　メソッド，クラスなど定義された場所の範囲内でのみ使用可能．クラスやメソッドを超えての参照はできず，定義された場所以外から参照をするとエラーになる．


# 定数


## 宣言

ルールはローカル変数と同じだが，定数は全て大文字で宣言する．最初の文字だけ大文字にする「キャメルケース」はクラス名などに用いられる．

```ruby
NAME="ruby"
Name="ruby" #クラス名と紛らわしいので定数としては使われない
```


## スコープ

定義されたクラスやモジュール内やクラスを継承しているクラスなどで参照できる．

```ruby
RUBY=2.78

puts RUBY
```

    2.78

クラス内で定義可能なので同じ定数名でもクラスごとに違う値をもつことができる．


# グローバル変数


## 宣言

変数名の一番初めに"$"をつけないといけない．

```ruby
$name="ruby"
```


## スコープ

ローカル変数の逆で，メソッドやクラスを超えて参照できる変数．定義した場所にとらわれず，プログラムのどこからでも参照や変更ができる．

```ruby
$name="ruby"

def greet
 p $name
end

greet
```

    "ruby"


# ブロック変数


## 宣言

ブロック内「{}(ブレース)もしくはdo ~ end 内」で「|」で囲むことで宣言できる．

```ruby

#複数行でまとめる場合
3.times do |i,x| 
end

#1行でまとめる場合
[1,2,3].inject {|sum, n| sum+n}
```


## スコープ

ブロック実行の時にブロック内で用いられる一時的な変数．繰り返しなどの処理を行う際，「ブロック変数」に値を代入しながら処理を行う．ブロック内からのみ参照可能．

```ruby
num=99
3.times do |i, x=num|
 num=i*10 
 p x 
end
```

    10


# インスタンス変数


## 宣言

変数の始めに「@」をつける．

    @name="ruby"


## スコープ

インスタンスメソッド内でのみ使用できる変数．インスタンスごとに異なる値を持つことができ，メソッドを超えて参照することができる．

```ruby
class User
 def initialize(name)
  @name=name
 end

 def put_name
  p @name
 end
end

user1=User.new("ruby")
user2=User.new("python")
user1.put_name
user2.put_name

```

    "ruby"
    "python"


# クラス変数


## 宣言

変数のはじめに「@@」をつける．

```ruby
@@name="ruby"
```


## スコープ

定義されたクラス内で共有する値を扱うことができる変数．他のインスタンスで使用しても同じクラス内であれば共通の値として扱われるので，クラス内では一つの値しか扱えない．クラスを継承したクラスからも参照できる．

```ruby
class Ruby
 @@number=1
 def foo
  puts @@number
 end
end

num=Ruby.new
num.foo
```

    1

```ruby
class Jewelry < Ruby
 def hoge
  puts @@number
 end
end

num2=Jewelry.new
num2.hoge
```

    1

このように，Rubyクラスを継承したJewelryクラスでもクラス変数にアクセスできていることが分かる．


# クラスインスタンス変数


## 宣言

インスタンス変数と同じく「@」で始まるが，定義される場所によりインスタンス変数と区別される．

```ruby
@class_instance_var="ruby"
```


## スコープ

クラス変数と同様，クラス内で定義し，定義されたクラス内でしか参照することができない．

インスタンス変数と同じく@で始まるが，クラスで定義されている場合はクラスインスタンス変数，インスタンス内で定義されている場合はインスタンス変数と定義されている場所で区別される．クラスを継承したクラスからは参照できないのがクラス変数との違い．

```ruby
class MyClass
 @class_instance_var="ruby"
 def sef.class_instance_var
  puts @class_instance_var
 end

 def class_instance_var
  puts @class_instance_var 
 end
end

instance=MyClass.new
instance.class_instance_var
```

    

インスタンスメソッド内では，インスタンス変数として認識されるので，クラスインスタンス変数にはアクセスできないことが分かる．

```ruby
 class MyClass
  @class_instance_var="ruby"
  def self.class_instance_var
   puts @class_instance_var
  end
  def class_instance_var
   puts @class_instance_var
  end
end

MyClass.class_instance_var
```

    ruby

クラスメソッドの場合はクラスインスタンス変数にアクセスできる．

```ruby
class SubClass < MyClass
 def self.class_instance_var_again
  puts @class_instance_var
 end
end

SubClass.class_instance_var_again
```

    

継承したクラスからはクラスインスタンス変数にアクセスできない．


# 参考文献

<https://www.sejuku.net/blog/12879>



------
 - **source** ~/grad_members_20f/members/NobuakiMori/L06_method.org