Skip to content

Instantly share code, notes, and snippets.

@t-oginogin
Created August 15, 2014 07:45
Show Gist options
  • Save t-oginogin/2ecc5365093c985fdd36 to your computer and use it in GitHub Desktop.
Save t-oginogin/2ecc5365093c985fdd36 to your computer and use it in GitHub Desktop.
ruby2.1.2でいろいろ操作した結果
# ===============
# ローカル変数のスコープ
# スコープ外はエラー
# ===============
x=1
def foo
puts x
end
foo
# sample1.rb:7:in `foo': undefined local variable or method `x' for main:Object (NameError)
# from sample1.rb:9:in `<main>'
# ===============
# ローカル変数のスコープ
# スコープ外はエラー
# ===============
def foo
x=1
end
puts x
# sample2.rb:8:in `<main>': 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:in `<main>'
# ===============
# クロージャー
# 束縛された変数はブロック内の変更がブロック外に反映される
# ===============
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
#
# ===============
# インスタンス変数とクラスインスタンス変数
# クラス内で定義した@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:in `<main>': undefined method `id=' for #<Foo:0x007f8e1b093b10 @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:in `<main>': 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=[2, 3]
# g=1
# h=[2, 3]
# ===============
# クラスメソッドとインスタンスメソッド追加
# 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,BasicObject
# B B,A,Object,Kernel,BasicObject
# C C,M,Object,Kernel,BasicObject
# D D,N,C,M,Object,Kernel,BasicObject
# a A,Object,Kernel,BasicObject
# ===============
# 探索パス
# 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:in `<main>': undefined method `foo' for #<A:0x007fea5b088980> (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:in `<main>': 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:0x007fe67323c880>
# ===============
# 探索パス
# 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:0x007fbc8b0933b0>, A
# M.foo #<A:0x007fbc8b0933b0>, 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,BasicObject
# #A #<Class:A>, Class, #<Class:Object>
# #A #<Class:A>,#<Class:Object>,#<Class:BasicObject>,Class,Module,Object,Kernel,BasicObject
# B B, Class, A
# B B,A,Object,Kernel,BasicObject
# #A.foo
# #B #<Class:B>, Class, #<Class:A>
# #B #<Class:B>,#<Class:A>,#<Class:Object>,#<Class:BasicObject>,Class,Module,Object,Kernel,BasicObject
# ===============
# 探索パス
# 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:0x007fa78923c098>
# ===============
# 探索パス
# クラスに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,BasicObject
# ===============
# 探索パス
# クラスに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:A>,#<Class:Object>,#<Class:BasicObject>,Class,Module,Object,Kernel,BasicObject
# #B #<Class:B>,#<Class:A>,#<Class:Object>,#<Class:BasicObject>,Class,Module,Object,Kernel,BasicObject
# #A.foo A
# #A A,Object,Kernel,BasicObject
# #B.foo B
# #B B,A,Object,Kernel,BasicObject
# #A.foo B
# #A B,A,Object,Kernel,BasicObject
# #A.foo C
# #A C,A,Object,Kernel,BasicObject
# ===============
# 探索パス
# オープンクラスでクラスメソッド再定義
# ===============
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)
# [[1, 2, 3]], [[]]
# [1], [[2, 3]]
# [1], [[2, 3]]
# ===============
# メソッド探索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:in `<main>': undefined method `foo' for #<Foo:0x007fd6caa3ca98> (NoMethodError)
# ===============
# ruby -d sample7.rb の結果
# ===============
puts "#{Module.constants}"
# -d有無のdiffを取ると
# (2.1.2要調査)
# > Debug # 1.8.7の場合
# > Verbose # 1.8.7の場合
# ===============
# ブロック確認
# ===============
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