Skip to content

Instantly share code, notes, and snippets.

@masassiez
Created January 18, 2012 08:13
Show Gist options
  • Save masassiez/1631921 to your computer and use it in GitHub Desktop.
Save masassiez/1631921 to your computer and use it in GitHub Desktop.
勉強メモ
# 定数参照
### ・クラス/モジュールで定義された定数は、その定数が定義されたクラス/モジュールに格納される
### ・クラス/モジュール定義の外(トップレベル)で定義された定数は Object に格納される
### ・メソッドの中では定義できません
## ネスト
### ・定数はその定数が定義されたクラス/モジュール定義の中(メソッドやネストしたクラス/モジュールも含む)から参照できる
CONST = "TOP"
module A
CONST = "A"
end
module A
class B
def B.get_const
CONST
end
end
end
A::B.get_const # => "A"
class A::B
CONST = "A::B"
end
A::B.get_const # => "A::B"
class B
CONST = "B"
def self.get_const
CONST
end
end
A::B.get_const # => "A::B"
B.get_const # => "B"
class A::C
def (A::C).get_const
CONST
end
end
A::C.get_const # => "TOP"
class A::C
CONST = "A::C"
end
A::C.get_const # => "A::C"
class C
CONST = "C"
class << self
def get_const
CONST
end
end
end
A::C.get_const # => "A::C"
C.get_const # => "C"
A.constants # => [:CONST, :B, :C]
A::B.constants # => [:CONST]
B.constants # => [:CONST]
A::C.constants # => [:CONST]
C.constants # => [:CONST]
## 継承とインクルード、優先順位
### ・クラスを継承しているクラス、モジュールをインクルードしているクラス/モジュールから参照できる
### ・定数参照時の定数の探索順序は、最初にネスト関係を外側に向かって探索し、次に継承関係を上位に向かって探索します
### ・トップレベルの定数定義はネストの外側とはみなされません。トップレベルの定数は、継承関係を探索した結果で参照されるので優先順位は低くなる
### ・トップレベルの定数定義は Object を明示的にすればネスト関係が先に探索されるためトップレベルの定数の優先順位を高くできる
class Foo
CONST = "Foo"
end
class Bar
CONST = "Bar"
end
module Baz
CONST = "Baz"
end
class FooFoo < Foo
CONST # => "Foo"
class BarBar < Bar
CONST # => "Bar"
end
end
class FooFoo < Foo
include Baz
CONST # => "Baz"
class BarBar < Bar
CONST # => "Bar"
end
end
class Object
class FooFoo < Foo
Module.nesting # => [FooFoo, Object]
CONST # => "TOP"
CONST = "FooFoo"
class BarBar < Bar
include Baz
Module.nesting # => [FooFoo::BarBar, FooFoo, Object]
CONST # => "FooFoo"
CONST = "BarBar"
CONST # => "BarBar"
Bar::CONST # => "Bar"
FooFoo::CONST # => "FooFoo"
Foo::CONST # => "Foo"
::CONST # => "TOP"
end
end
end
# エイリアス
## Module#alias_method (private)
## alias_method(new, original) -> self
### ・メソッド名は String または Symbol で指定します
### ・メソッドの定義内で別名を付けることができます
### ・グローバル変数の別名をつけることはできません
### ・クラスメソッドに対して使用することはできません
## alias式
## alias 新メソッド名 旧メソッド名
## alias 新グローバル変数名 旧グローバル変数名
### ・メソッド名には識別子そのものか Symbol を指定します
### ・メソッドあるいはグローバル変数に別名をつけます
### ・正規表現の部分文字列に対応する変数 $1,$2, ... には別名を付けることができません
def foo ; end; def bar ; end; # !> previous definition of foo was here
alias foo bar # !> method redefined; discarding old foo
alias :foo :bar
alias $MATCH $&
def meth
"original"
end
alias original meth
def meth
"new"
end
meth # => "new"
original # => "original"
# 特異メソッドとインスタントメソッド
## Class.new
## new(superclass = Object) -> Class
## new(superclass = Object) {|klass| ... } -> Class
### ・新しく名前の付いていない superclass のサブクラスを生成します
### ・名前のないクラスは、最初に名前を求める際に代入されている定数名を検索し、見つかった定数名をクラス名とします
p obj = Class.new # => #<Class:0x007fe3db8240f8>
p obj.name # => nil
Foo = obj # ここで p foo すれば "Foo" 固定 # !> already initialized constant Foo
Bar = obj # !> already initialized constant Bar
p obj.name # 不定(FooかBar)
## Class#new
## new(*args, &block) -> object
### ・自身のインスタンスを生成して返します
### ・Class#allocate でインスタンスを生成し、 Object#initialize で初期化を行います
# メソッド
### ・クラスまたはモジュール定義内に修飾子なしのメソッド名でメソッドを定義するとインスタンスメソッドがされる
### ・クラスまたはモジュール定義外で修飾子なしのメソッド名でメソッドを定義すると Object クラスに private メソッドが追加される
### ・修飾子が定数、式のメソッド名でメソッドを定義すると、その定数または式の値であるオブジェクトに関連付けられたメソッドが追加され、呼び出すには、その式によって参照されるオブジェクトをレシーバとして指定する必要がある。この形式によってオブジェクトごとにメソッドが定義されます。このようなメソッドを特異メソッドと呼びます
## 特異メソッド
class MyClass
def MyClass.meth_a1
"meth_a1"
end
class << MyClass
def meth_a2 # 修飾子なしでも特異メソッド
"meth_a2"
end
end
def self.meth_b1
"meth_b1"
end
class << self
def meth_b2 # 修飾子なしでも特異メソッド
"meth_b2"
end
end
end
MyClass.meth_a1 # => "meth_a1"
MyClass.meth_a2 # => "meth_a2"
MyClass.meth_b1 # => "meth_b1"
MyClass.meth_b2 # => "meth_b2"
obj = Object.new
def obj.method
"obj.method"
end
obj.method # => "obj.method"
def (0.class).one
Integer(1)
end
Fixnum.one # => 1
def (MyClass.new.class).meth_c
"meth_c"
end
MyClass.meth_c # => "meth_c"
## ネストされたメソッド
### ・
def count # !> previous definition of count was here
def count # !> previous definition of count was here
def count # !> previous definition of count was here
def count # !> previous definition of count was here
def count # !> method redefined; discarding old count
"5"
end
"4"
end
"3"
end
"2"
end
"1"
end
5.times{
count # => "1", "2", "3", "4", "5"
}
# 配列の各要素は全て同一の文字列を指す例
## new(size = 0, val = nil) -> Array
a = Array.new(3, "a") # => ["a", "a", "a"]
a[0].upcase!
a # => ["A", "A", "A"]
# 配列の各要素は全て異なる文字列を指す例
## new(size) {|index| ... } -> Array
### インデックスなし
a = Array.new(3){ "a" } # => ["a", "a", "a"]
a[0].upcase!
a # => ["A", "a", "a"]
### インデックスあり
a = Array.new(3){ |i| (i+97).chr } # => ["a", "b", "c"]
a[0].upcase!
a # => ["A", "b", "c"]
## 配列リテラル
a = ["a", "b", "c",] # => ["a", "b", "c"]
a == [*"a".."c"] # => true
a[0].upcase!
a # => ["A", "b", "c"]
## 文字列配列リテラル
a = %w( a b c ) # => ["a", "b", "c"]
a == %W[ a b c ] # => true
a == %W!#{97.chr} #{98.chr} #{99.chr}! # => true
a[0].upcase!
a # => ["A", "b", "c"]
## その他
a = "a", "b", "c" # => ["a", "b", "c"]
a == "abc".split(//) # => true
a == "abc".scan(/./) # => true
a == ("a".."c").to_a # => true
a == (97..99).map(&:chr) # => true
a[0].upcase!
a # => ["A", "b", "c"]
# 要素を複製しない浅い複製(要素を共有)例
## new(ary) -> Array
a = ["a", "a", "a"] # => ["a", "a", "a"]
b = Array.new(a) # => ["a", "a", "a"]
a[0].upcase!
b # => ["A", "a", "a"]
## dup -> Array
a = ["a", "a", "a"] # => ["a", "a", "a"]
b = a.dup # => ["a", "a", "a"]
a[0].upcase!
b # => ["A", "a", "a"]
# 丸め誤差
## 影響大
10.times.inject(0.0) { |t, _| t + 0.1 } == 1.0 ? "EQ" : "NEQ" # => "NEQ"
## 影響小
require 'bigdecimal'
10.times.inject(BigDecimal("0.0")) { |t, _| t + BigDecimal("0.1") } == 1.0 ? "EQ" : "NEQ" # => "EQ"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment