Created
August 14, 2014 09:22
-
-
Save t-oginogin/dafa9cba37f38c56270d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ruby1.8.7でいろいろ操作した結果 | |
# =============== | |
# ローカル変数のスコープ | |
# スコープ外はエラー | |
# =============== | |
x=1 | |
def foo | |
puts x | |
end | |
foo | |
# sample1.rb:7:in `foo': undefined local variable or method `x' for main:Object (NameError) | |
# from silver/sample1.rb:9 | |
# =============== | |
# ローカル変数のスコープ | |
# スコープ外はエラー | |
# =============== | |
def foo | |
x=1 | |
end | |
puts x | |
# sample2.rb:8: undefined local variable or method `x' for main:Object (NameError) | |
# =============== | |
# クロージャー | |
# 束縛された変数にはアクセス可能 | |
# =============== | |
def foo | |
x=1 | |
3.times {puts x} | |
end | |
foo | |
# 1 | |
# 1 | |
# 1 | |
# =============== | |
# ブロックのスコープ | |
# 束縛された変数ではないのでエラー | |
# =============== | |
def foo | |
3.times {x=1} | |
puts x | |
end | |
foo | |
# sample4.rb:7:in `foo': undefined local variable or method `x' for main:Object (NameError) | |
# from sample4.rb:9 | |
# =============== | |
# クロージャー | |
# 束縛された変数はブロック内の変更がブロック外に反映される | |
# =============== | |
def foo | |
x=1 | |
3.times {x=2;puts x} | |
puts x | |
end | |
foo | |
# 2 | |
# 2 | |
# 2 | |
# 2 | |
# =============== | |
# グローバル変数とクラス変数の文字列への埋め込み | |
# グローバル変数とクラス変数は{}省略可能 | |
# =============== | |
$title="RUBY" | |
puts "test #{$title}" | |
puts "test #$title" | |
puts 'test #{$title}' | |
puts 'test #$title' | |
@title="RUBY" | |
puts "test #{@title}" | |
puts "test #@title" | |
puts 'test #{@title}' | |
puts 'test #@title' | |
# test RUBY | |
# test RUBY | |
# test #{$title} | |
# test #$title | |
# test RUBY | |
# test RUBY | |
# test #{@title} | |
# test #@title | |
# =============== | |
# 正規表現の"|"の動き | |
# /^Y|yes$/は(先頭Yで始まる)または(yesで終わる)の意味 | |
# =============== | |
puts "Yes" =~ /^Y|yes$/ | |
puts "Y" =~ /^Y|yes$/ | |
puts "Yyes" =~ /^Y|yes$/ | |
puts "oyes" =~ /^Y|yes$/ | |
puts "es" =~ /^Y|yes$/ | |
# 0 | |
# 0 | |
# 0 | |
# 1 | |
# nil | |
# =============== | |
# インスタンス変数とクラスインスタンス変数 | |
# クラス内で定義した@idはくらすインスタンス変数であり、 | |
# インスタンス内にはいない | |
# クラスインスタンス変数にアクセスするにはself.id、self.id=等を定義する | |
# インスタンス変数はインスタンスのスコープ内で定義する必要がある | |
# attr_reader等はクラスの外でfoo.idのような場合のアクセス用 | |
# =============== | |
class Foo | |
@id = 0 | |
attr_reader :id | |
def method1 | |
@id = 1 | |
puts "foo.@id = #{@id}" | |
end | |
puts "Foo.@id = #{@id}" | |
end | |
class FooExt < Foo | |
def method2 | |
puts "fooExt.@id = #{@id}" | |
@id = 2 | |
puts "fooExt.@id = #{@id}" | |
end | |
end | |
foo = Foo.new | |
foo.method1 | |
fooExt = FooExt.new | |
fooExt.method1 | |
fooExt.method2 | |
foo.id = 3 # errorになる | |
# Foo.@id = 0 | |
# foo.@id = 1 | |
# foo.@id = 1 | |
# fooExt.@id = 1 | |
# fooExt.@id = 2 | |
# sample8.rb:34: undefined method `id=' for #<Foo:0x1012994e0 @id=1> (NoMethodError) | |
# =============== | |
# クラス変数 | |
# クラス変数のスコープはサブクラスを含めクラス領域、インスタンス領域で同じ | |
# =============== | |
class Foo | |
@@a = 0; | |
def method1 | |
@@a += 1 | |
puts @@a | |
end | |
end | |
foo = Foo.new | |
foo.method1 | |
foo.method1 | |
# 1 | |
# 2 | |
# =============== | |
# メソッド探索 | |
# トップレベルのメソッドはObjectクラスのプライベートメソッド | |
# =============== | |
def foo | |
puts "foo" | |
end | |
class Foo | |
foo | |
# self.foo # プライベートメソッドなのレシーバをつけるとエラー | |
def bar | |
foo | |
end | |
def foo | |
puts "Foo.foo" | |
end | |
end | |
Foo.new.foo | |
Foo.new.bar | |
# foo | |
# Foo.foo | |
# Foo.foo | |
# =============== | |
# 正規表現の?確認 | |
# ?ありは最小、?なしは最長にマッチさせる | |
# =============== | |
"Bibbidy-Bobbidy-Boo" =~ /(B.bbidy-)+?/ | |
puts $~ | |
"Bibbidy-Bobbidy-Boo" =~ /(B.bbidy-)+/ | |
puts $~ | |
# Bibbidy- | |
# Bibbidy-Bobbidy- | |
# =============== | |
# 例外のrescue確認 | |
# rescueはデフォルトStandardError | |
# =============== | |
class Err < StandardError | |
end | |
begin | |
raise Err | |
rescue | |
puts "1" | |
rescue StandardError => e | |
puts "2" | |
end | |
# 1 | |
# =============== | |
# 引数確認 | |
# 多重引数で引数なし | |
# =============== | |
def foo(*arg) | |
puts "foo" | |
end | |
foo("a") | |
foo | |
# foo | |
# foo | |
# =============== | |
# selfのclassとsuperclass確認 | |
# ModuleのクラスはModule | |
# Foo,Foo1のクラスはClass | |
# foo,foo1のクラスはFoo,Foo1 | |
# インスタンスメソッド内のselfのクラスはレシーバクラス | |
# superclassにはModule名は出てこないが、メソッドチェーンにはsuperclassの位置として挟み込まれる | |
# Moduleは初回の1度しかincludeされない(2回目以降は無効) | |
# =============== | |
module M | |
puts "M #{self.class}" | |
# puts "M #{self.superclass}" # error | |
def bar | |
puts "M #{self.class}" | |
end | |
end | |
module N | |
def bar | |
puts "N #{self.class}" | |
end | |
end | |
class Foo | |
include M | |
puts "Foo #{self.class}" | |
puts "Foo superclass #{self.superclass}" | |
def foo | |
puts "Foo #{self.class}" | |
# puts "Foo superclass #{self.superclass}" # error | |
end | |
end | |
class Foo1 < Foo | |
include N | |
include M | |
puts "Foo1 #{self.class}" | |
puts "Foo1 superclass #{self.superclass}" | |
end | |
Foo.new.foo | |
Foo1.new.foo | |
Foo.new.bar | |
Foo1.new.bar | |
# M Module | |
# Foo Class | |
# Foo superclass Object | |
# Foo1 Class | |
# Foo1 superclass Foo | |
# Foo Foo | |
# Foo Foo1 | |
# M Foo | |
# N Foo1 | |
# =============== | |
# インスタンスメソッド | |
# クラス内でincludeしたModuleのメソッドはインスタンスメソッド | |
# =============== | |
module M | |
def foo | |
puts "M.foo" | |
end | |
end | |
class Foo | |
include M | |
end | |
Foo.new.foo | |
Foo.foo | |
# M.foo | |
# sample14.rb:16: undefined method `foo' for Foo:Class (NoMethodError) | |
# =============== | |
# 配列の多重代入 | |
# =============== | |
a,b = [1,2,3] | |
puts "a=#{a}" | |
puts "b=#{b}" | |
c,d = *[1,2,3] | |
puts "c=#{c}" | |
puts "d=#{d}" | |
e,*f = [1,2,3] | |
puts "e=#{e}" | |
puts "f=#{f}" | |
g,*h = *[1,2,3] | |
puts "g=#{g}" | |
puts "h=#{h}" | |
# a=1 | |
# b=2 | |
# c=1 | |
# d=2 | |
# e=1 | |
# f=23 | |
# g=1 | |
# h=23 | |
# =============== | |
# クラスメソッドとインスタンスメソッド追加 | |
# objにextendしたModuleのメソッドはインスタンスメソッド | |
# クラスにextendしたModuleのメソッドはクラスメソッド | |
# =============== | |
module M | |
def foo | |
puts "M.foo" | |
end | |
end | |
obj = Object.new | |
obj.extend M | |
obj.foo | |
# Object.foo # error | |
Object.extend M | |
Object.foo | |
# M.foo | |
# M.foo | |
# =============== | |
# 探索パス | |
# ancestorsはModuleのメソッドなのでレシーバはクラス層 | |
# クラス定義内でのextendはクラス層への挟み込み | |
# 同じModuleのincludeは1回目のみ有効 | |
# =============== | |
module M | |
end | |
module N | |
end | |
class A | |
end | |
class B < A | |
extend M | |
end | |
class C | |
include M | |
extend M | |
end | |
class D < C | |
include N | |
include M # 無効 | |
extend N | |
extend M | |
end | |
a = A.new | |
a.extend M | |
puts "A #{A.ancestors.join(",")}" | |
puts "B #{B.ancestors.join(",")}" | |
puts "C #{C.ancestors.join(",")}" | |
puts "D #{D.ancestors.join(",")}" | |
puts "a #{a.class.ancestors.join(",")}" | |
# A A,Object,Kernel | |
# B B,A,Object,Kernel | |
# C C,M,Object,Kernel | |
# D D,N,C,M,Object,Kernel | |
# a A,Object,Kernel | |
# =============== | |
# 探索パス | |
# objにextendしたメソッドは特異クラスがクラスとの間に挟み込まれるので、 | |
# 自分のクラスの同メソッドより先に検出される | |
# objにextendしたメソッドはインスタンスメソッド | |
# クラスにextendしたメソッドはクラスメソッド | |
# =============== | |
module M | |
def foo | |
puts "M.foo" | |
end | |
end | |
module N | |
def foo | |
puts "N.foo" | |
end | |
end | |
module O | |
def foo | |
puts "O.foo" | |
end | |
end | |
class A | |
include M | |
extend N | |
end | |
class B | |
extend M | |
include N | |
end | |
a = A.new | |
print "a "; a.foo | |
b = B.new | |
print "b "; b.foo | |
print "A "; A.foo | |
print "B "; B.foo | |
a.extend O | |
print "a.extend "; a.foo | |
print "A "; A.foo | |
b.extend O | |
print "b.extend "; b.foo | |
print "B "; B.foo | |
# a M.foo | |
# b N.foo | |
# A N.foo | |
# B M.foo | |
# a.extend O.foo | |
# A N.foo | |
# b.extend O.foo | |
# B M.foo | |
# =============== | |
# 探索パス | |
# module内でself.fooとしてメソッド定義するとmoduleクラスのクラスメソッド | |
# =============== | |
module M | |
def self.foo | |
puts "M.foo" | |
end | |
end | |
class A | |
include M | |
end | |
M.foo | |
a = A.new | |
a.foo | |
# M.foo | |
# sample19.rb:17: undefined method `foo' for #<A:0x10ac4f2d8> (NoMethodError) | |
# =============== | |
# self確認 | |
# Module内のselfはModule | |
# Module内のメソッドのselfはレシーバ | |
# FooのclassはClass(Classのインスタンス) | |
# =============== | |
module M | |
$var1 = self.class | |
def foo | |
$var2 = self.class | |
end | |
end | |
class Foo | |
$var3 = self.class | |
include M | |
def foo1 | |
$var4 = self.class | |
end | |
end | |
$var5 = Foo.new.foo | |
puts "var1 #{$var1}" | |
puts "var2 #{$var2}" | |
puts "var3 #{$var3}" | |
puts "var4 #{$var4}" | |
puts "var5 #{$var5}" | |
# var1 Module | |
# var2 Foo | |
# var3 Class | |
# var4 | |
# var5 Foo | |
# =============== | |
# 探索パス | |
# moduleクラス内でself.fooとメソッドを宣言するとmoduleクラスのクラスメソッド | |
# =============== | |
module M | |
def self.foo | |
puts "M.foo" | |
end | |
end | |
class A | |
include M | |
end | |
M.foo | |
A.foo | |
# M.foo | |
# sample20.rb:16: undefined method `foo' for A:Class (NoMethodError) | |
# =============== | |
# 探索パス | |
# module内のselfはmodule名、module内のメソッド内のselfはレシーバ | |
# =============== | |
module M | |
puts "M #{self}" | |
def foo | |
puts "M.foo #{self}" | |
end | |
end | |
class A | |
include M | |
end | |
A.new.foo | |
# M M | |
# M.foo #<A:0x10e43e298> | |
# =============== | |
# 探索パス | |
# module内のselfはmodule名、そのclassはModule | |
# module内のメソッド内のselfはレシーバ、そのclassはレシーバクラス | |
# =============== | |
module M | |
puts "M #{self}, #{self.class}" | |
def foo | |
puts "M.foo #{self}, #{self.class}" | |
end | |
end | |
module N | |
puts "N #{self}, #{self.class}" | |
def foo | |
puts "N.foo #{self}, #{self.class}" | |
end | |
end | |
class A | |
def foo | |
puts "A.foo #{self}, #{self.class}" | |
end | |
include N | |
end | |
a = A.new | |
a.foo | |
a.extend M | |
a.foo | |
# M M, Module | |
# N N, Module | |
# A.foo #<A:0x10df72f20>, A | |
# M.foo #<A:0x10df72f20>, A | |
# =============== | |
# 探索パス | |
# class AのclassはClass、superclassはObject | |
# class B < AのclassはClass、superclassはA | |
# 特異クラス内のclassはClass、superclassはClassの特異クラス | |
# =============== | |
class A | |
puts "A #{self}, #{self.class}, #{self.superclass}" | |
puts "A #{self.ancestors.join(",")}" | |
def self.foo | |
puts "A.foo" | |
end | |
class << self | |
puts "#A #{self}, #{self.class}, #{self.superclass}" | |
puts "#A #{self.ancestors.join(",")}" | |
def foo | |
puts "#A.foo" | |
end | |
end | |
end | |
class B < A | |
puts "B #{self}, #{self.class}, #{self.superclass}" | |
puts "B #{self.ancestors.join(",")}" | |
foo | |
class << self | |
puts "#B #{self}, #{self.class}, #{self.superclass}" | |
puts "#B #{self.ancestors.join(",")}" | |
# foo # error | |
# self.foo # error | |
end | |
end | |
# A A, Class, Object | |
# A A,Object,Kernel | |
# #A #<Class:A>, Class, #<Class:Class> | |
# #A Class,Module,Object,Kernel | |
# B B, Class, A | |
# B B,A,Object,Kernel | |
# #A.foo | |
# #B #<Class:B>, Class, #<Class:Class> | |
# #B Class,Module,Object,Kernel | |
# =============== | |
# 探索パス | |
# objにextendしたmoduleのメソッドは最初に検索される | |
# =============== | |
module M | |
def foo | |
puts "M.foo #{self}" | |
end | |
end | |
module N | |
def foo | |
puts "N.foo #{self}" | |
end | |
end | |
class A | |
def foo | |
puts "A.foo" | |
end | |
include M | |
end | |
a = A.new | |
a.extend N | |
a.foo | |
# N.foo #<A:0x102c3db30> | |
# =============== | |
# 探索パス | |
# クラスにextendしたmoduleは自分のクラスの上に挟み込まれる | |
# 自分のクラスのメソッドが先に検索される | |
# =============== | |
module M | |
def foo | |
puts "M.foo #{self} #{self.class}" | |
end | |
end | |
module N | |
def foo | |
puts "N.foo #{self} #{self.class}" | |
end | |
end | |
class A | |
def self.foo | |
puts "A.foo" | |
end | |
extend M | |
end | |
A.extend N | |
A.foo | |
puts "#{A.ancestors.join(",")}" | |
# A.foo | |
# A,Object,Kernel | |
# =============== | |
# 探索パス | |
# クラスにextendされたmoduleは自分のクラスの上に挟み込まれる | |
# =============== | |
module M | |
def foo | |
puts "M.foo #{self}" | |
end | |
end | |
module N | |
def foo | |
puts "N.foo #{self}" | |
end | |
end | |
class A | |
extend M | |
end | |
A.extend N | |
A.foo | |
# N.foo A | |
# =============== | |
# 探索パス | |
# class << selfで、includeではなく直接同名メソッド定義すると単なる上書き | |
# =============== | |
class A | |
def self.foo | |
puts "A.foo" | |
end | |
class << self | |
puts "#A #{self.ancestors.join(",")}" | |
def foo | |
puts "#A.foo #{self}" | |
puts "#A #{self.ancestors.join(",")}" | |
end | |
end | |
end | |
class B < A | |
class << self | |
puts "#B #{self.ancestors.join(",")}" | |
def foo | |
puts "#B.foo #{self}" | |
puts "#B #{self.ancestors.join(",")}" | |
super | |
end | |
end | |
end | |
class C < A | |
def self.foo | |
super | |
end | |
end | |
A.foo | |
B.foo | |
C.foo | |
# #A Class,Module,Object,Kernel | |
# #B Class,Module,Object,Kernel | |
# #A.foo A | |
# #A A,Object,Kernel | |
# #B.foo B | |
# #B B,A,Object,Kernel | |
# #A.foo B | |
# #A B,A,Object,Kernel | |
# #A.foo C | |
# #A C,A,Object,Kernel | |
# =============== | |
# 探索パス | |
# オープンクラスでクラスメソッド再定義 | |
# =============== | |
class A | |
def self.foo | |
puts "A.foo old" | |
end | |
end | |
class A | |
def self.foo | |
puts "A.foo new" | |
end | |
end | |
A.foo | |
# A.foo new | |
# =============== | |
# メソッド探索 | |
# インスタンスメソッドとクラスメソッド | |
# =============== | |
class Foo | |
@a = 1 | |
def foo | |
@a = 2 | |
end | |
class << self | |
@a = 3 | |
def foo | |
@a = 4 | |
end | |
end | |
end | |
puts Foo.new.foo | |
puts Foo.foo | |
# 2 | |
# 4 | |
# =============== | |
# 探索パス | |
# クラスの特異クラスはクラスの後に探索される | |
# =============== | |
module M | |
def foo | |
puts "M.foo #{self}" | |
super | |
end | |
end | |
class Object | |
class << self | |
def foo | |
puts "#Object.foo #{self} #{self.class}" | |
end | |
end | |
end | |
class A | |
def self.foo | |
puts "A.foo #{self} #{self.class}" | |
end | |
extend M | |
end | |
class B < A | |
extend M | |
end | |
A.foo | |
B.foo | |
A.extend M | |
A.foo | |
# A.foo A Class | |
# A.foo B Class | |
# A.foo A Class | |
# =============== | |
# 探索パス | |
# 特異クラスで定義されたメソッドのsuperは、特異クラスのsuperclassを探索する | |
# =============== | |
module M | |
def foo | |
puts "M.foo #{self} #{self.class}" | |
super | |
end | |
end | |
module N | |
def foo | |
puts "N.foo #{self} #{self.class}" | |
super | |
end | |
end | |
module O | |
def foo | |
puts "O.foo #{self} #{self.class}" | |
super | |
end | |
end | |
class Object | |
class << self | |
def foo | |
puts "#Object.foo #{self} #{self.class}" | |
end | |
end | |
end | |
class A | |
# def self.foo | |
# puts "A.foo #{self} #{self.class}" | |
# end | |
extend M | |
class << self | |
include N | |
end | |
end | |
class B < A | |
end | |
A.foo | |
B.foo | |
A.extend O | |
A.foo | |
# N.foo A Class | |
# M.foo A Class | |
# #Object.foo A Class | |
# N.foo B Class | |
# M.foo B Class | |
# #Object.foo B Class | |
# O.foo A Class | |
# N.foo A Class | |
# M.foo A Class | |
# #Object.foo A Class | |
# =============== | |
# 引数確認 | |
# *は多重引数 | |
# =============== | |
def foo(a, *b) | |
puts "[#{a}], [#{b}]" | |
end | |
arg = [1,2,3] | |
foo(arg) | |
foo(*arg) | |
foo(1,2,3) | |
# [123], [] | |
# [1], [23] | |
# [1], [23] | |
# =============== | |
# メソッド探索super | |
# Moduleをincludeするとsuperclassとの間に挟み込まれる | |
# super呼び出しのチェーンにも挟み込まれる | |
# 自分のclassのメソッドが一番最初 | |
# =============== | |
module M | |
def foo | |
puts "M.foo" | |
end | |
end | |
class C1 | |
def foo | |
super | |
puts "C1.foo" | |
end | |
end | |
class C2 < C1 | |
include M | |
def foo | |
super | |
puts "C2.foo" | |
end | |
end | |
C2.new.foo | |
# M.foo | |
# C2.foo | |
# =============== | |
# クラスメソッド | |
# class内でextendするとクラスメソッド | |
# =============== | |
module M | |
def foo | |
puts "foo" | |
end | |
end | |
class Foo | |
extend M | |
end | |
Foo.foo | |
Foo.new.foo | |
# foo | |
# sample6.rb:16: undefined method `foo' for #<Foo:0x10a43e418> (NoMethodError) | |
# =============== | |
# ruby -d sample7.rb の結果 | |
# =============== | |
puts "#{Module.constants}" | |
# -d有無のdiffを取ると | |
# > Debug | |
# > Verbose | |
# =============== | |
# ブロック確認 | |
# =============== | |
2.downto(0) do |i| puts i end | |
2.downto(0) {|i| puts i} | |
2.downto 0 do |i| puts i end | |
#2.downto 0 {|i| puts i} # error | |
# 2 | |
# 1 | |
# 0 | |
# 2 | |
# 1 | |
# 0 | |
# 2 | |
# 1 | |
# 0 | |
# =============== | |
# alias名前 | |
# 識別子かシンボル | |
# =============== | |
def method | |
puts "a" | |
end | |
alias old_method method | |
alias :new_method :old_method | |
def method | |
puts "b" | |
end | |
new_method | |
method | |
# a | |
# b | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment