SHOYAN BLOG

[Ruby]オブジェクトの設定情報を保持するパターンの紹介

オブジェクトの設定情報を保持するパターンを紹介します。
このパターンを使えば設定情報を管理するクラスに集約することができ、コードの見通しがよくなります。また、初期設定の定義ができるようになります。

名前空間で区切ってConfigurationモデルに設定を持たせるようにします。
そして、トップにconfigurationとconfigureメソッドを定義します。
クラスメソッドで定義するのがポイントです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Hoge
  class Configuration
    def initialize
      @name = nil
    end
    attr_accessor :name

  end

  def self.configuration
    @configuration ||= Hoge::Configuration.new
  end

  def self.configure
    yield configuration if block_given?
  end
end

configureメソッドは以下のように初期設定したいパラメーターを設定するために使います。

1
2
3
4
5
6
7
Hope.configure do |config|
  config.name = 'shoyan'
end

config = Hoge.configuration
config.name
=> "shoyan"

configureメソッドで設定した情報が保持されています。
初期設定はできるようになりました。

次はこの設定情報を内部で参照するようにします。

Hopeクラスのinitializeメソッドで設定情報をインスタンス変数に保存します。

1
2
3
4
5
6
7
8
9
class Hoge
  def initialize
    @config = Hoge.configuration
  end

  def greeting
    puts "Hello #{@config.name}"
  end
end

実行してみます。
Hope::Configurationの値が出力されていますね。

1
2
3
hoge = Hoge.new
hope.greeting
=> Hello shoyan

Hoge.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Hoge
  class Configuration
    def initialize
      @name = nil
    end
    attr_accessor :name
  end

  def initialize
    @config = Hoge.configuration
  end

  def greeting
    puts "Hello #{@config.name}"
  end

  def self.configuration
    @configuration ||= Hoge::Configuration.new
  end

  def self.configure
    yield configuration if block_given?
  end
end

Rubyのロード機構について

Rubyはロード機構として、以下を備えています。

  • require
  • load
  • autoload
  • require_relative

require

requireは以下の特徴を備えています。

  • ロードパスからファイルを探してくる
  • 拡張ライブラリもロードできる
  • 拡張子 .rb / .so を省略できる
  • 同じファイルは2度以上ロードしない

Rubyのロードパスは $:に入っています。
私の環境では以下のように表示されました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[1] pry(main)> puts $:
/Users/shoyan/.rbenv/rbenv.d/exec/gem-rehash
/Users/shoyan/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/did_you_mean-1.0.0/lib
/Users/shoyan/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/coderay-1.1.1/lib
/Users/shoyan/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/slop-3.6.0/lib
/Users/shoyan/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/method_source-0.8.2/lib
/Users/shoyan/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/pry-0.10.3/lib
/Users/shoyan/.rbenv/versions/2.3.0/lib/ruby/site_ruby/2.3.0
/Users/shoyan/.rbenv/versions/2.3.0/lib/ruby/site_ruby/2.3.0/x86_64-darwin14
/Users/shoyan/.rbenv/versions/2.3.0/lib/ruby/site_ruby
/Users/shoyan/.rbenv/versions/2.3.0/lib/ruby/vendor_ruby/2.3.0
/Users/shoyan/.rbenv/versions/2.3.0/lib/ruby/vendor_ruby/2.3.0/x86_64-darwin14
/Users/shoyan/.rbenv/versions/2.3.0/lib/ruby/vendor_ruby
/Users/shoyan/.rbenv/versions/2.3.0/lib/ruby/2.3.0
/Users/shoyan/.rbenv/versions/2.3.0/lib/ruby/2.3.0/x86_64-darwin14

load

loadもrequireと同じくロードパスからファイルを探してロードします。
しかし、requireのように拡張ライブラリはロードできません。
また、ロードできるファイルもRubyプログラムだけです。
requireのように2回以上の読み込みを制御する機構もなく、callされた回数分ファイルは読み込まれます。

autoload

autoloadはrequireと似ていますが、すぐには読み込まれず、必要になった段階でrequrieされます。以下、サンプルコードです。

autoload.rb

1
2
autoload :Outer, './outer'
puts Outer.new

outer.rb

1
2
3
4
class Outer
end

puts 'Outer loaded!'

実行すると、Outerがloadされているのが確認できます。

1
2
3
  ruby autoload.rb
Outer loaded!
#<Outer:0x007fcc14040e60>

autoloadはネストされたクラスやモジュールもloadすることができます。

autoload.rb

1
2
3
autoload :Outer, './outer'
puts Outer.new
puts Outer::Inner.new

outer.rb

1
2
3
4
5
class Outer
  autoload :Inner, './inner'
end

puts 'Outer loaded!'

inner.rb

1
2
3
4
5
6
class Outer
  class Inner
  end
end

puts "Outer::Inner loaded!"

実行すると、Outer::Innerがloadされているのが確認できます。

1
2
3
4
5
  ruby autoload.rb
Outer loaded!
#<Outer:0x007f9fd4054df0>
Outer::Inner loaded!
#<Outer::Inner:0x007f9fd404f990>

require_relative

あまり見かけることがありませんが、require_relative というメソッドがRuby1.9.2から追加されています。
例えばrequireで同じ階層のファイルをロードする場合は、require './filename' のように明示的に./を指定する必要があります。
require_relativeを使えば、require_relative 'filename' のように定義することができます。

Iptablesことはじめ

iptablesの概念と設定方法を調べました。

iptablesとは

iptablesとはパケットをフィルタリングするためのツールです。
また、NATとしても使えます。

iptablesの用語

iptablesを理解するにあたって必要な用語をまとめました。

TARGETS

iptablesのルールを設定する際に、targetを指定します。
targetはユーザー定義のものと特別なtargetである、ACCEPT, DROP, QUEUE or RETURNがあります。
パケットに対してどんな操作をするかを定義します。

代表的なtargetです。

ACCEPT
パケットを通す
DROP
パケットを破棄する
QUEUE
パケットをキューにためる
RETURN
チェインを辿るのをストップして、評価を行う
REJECT
パケットを破棄し、エラーパケットを返す
DNAT
送信先IPアドレスを変更する
SNAT
送信元IPアドレスを変更する
MASQUERADE
複数の送信元IPアドレスを変更(マスカレード)する
LOG
ログを出力する

Chain

iptablesを設定する際にchainを指定します。
chainにはビルトインchainとユーザー定義chainがあります。
chainはパケットに対する実行条件を定義します。

ビルトインchainは以下です。

INPUT
FORWARD
OUTPUT
PREROUTING
POSTROUTING

TABLES

一般的にはフィルタリングとして使われることが多いiptablesですが、他にも様々な機能があります。
iptablesにはそれをtableという概念で扱っており、5つのtableがあります。

filter
パケットのフィルタリングを設定するためのテーブルです。
デフォルトのテーブルです。tableオプションを明示的に指定しない場合は、filterが指定されたことになります。
INPUT、FORWARD、OUTPUTのChainを含みます。

nat
IPアドレスの変換を設定するためのテーブルです。
PREROUTING、POSTROUTING のChainを含みます。

mangle
パケットの書き換えを設定するためのテーブルです。

raw
接続の追跡の除外の設定をするためのテーブルです。

security
アクセスコントロールの設定をするためのテーブルです。

OPTIONS

iptablesのコマンドにオプションを指定できます。
オプションはいくつかのグループに区別されます。

COMMANDS

iptablesに実行してほしいコマンドを指定します。
以下のようなコマンドがあります。

-A, –append
選択したチェインにルールを追加します。

-C, –check
指定したチェインにルールが存在するかをチェックします。

-D, –delete
チェインからルールを消します。

詳細はiptablesのmanをご覧ください。

PARAMETERS

ルールを作成する際に指定するパラメーターです。

-p, –protocol
ルールの対象となるプロトコルを指定します。

-j, –jump
ルールの対象となるtargetを指定します。

-s, –source
ルールの対象となるアドレスを指定します。
例えば、IPアドレス、ホスト名、ネットワーク名などを指定します。

詳細はiptablesのmanをご覧ください。

OTHER OPTIONS

追加オプションです。

-v, –verbose
詳細表示のオプションです。

詳細はiptablesのmanを参照ください。

iptablesの基本的な構文

基本的には以下のように指定します。

1
iptables [-t table] command chain options target

例えば、ローカルホストからのping(icmp)を許可する場合は以下となります。

1
iptables -A INPUT -p icmp -j ACCEPT

iptablesの基本的な読み方

現在のiptablesの設定を表示するには、iptables -L コマンドを使います。

1
2
3
4
5
6
7
8
9
10
11
12
Example: Input Chain Rule Table Listing
Chain INPUT (policy DROP)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             anywhere
DROP       all  --  anywhere             anywhere             ctstate INVALID
UDP        udp  --  anywhere             anywhere             ctstate NEW
TCP        tcp  --  anywhere             anywhere             tcp flags:FIN,SYN,RST,ACK/SYN ctstate NEW
ICMP       icmp --  anywhere             anywhere             ctstate NEW
REJECT     udp  --  anywhere             anywhere             reject-with icmp-port-unreachable
REJECT     tcp  --  anywhere             anywhere             reject-with tcp-reset
REJECT     all  --  anywhere             anywhere             reject-with icmp-proto-unreachable

1行目がChainの名前で、次にデフォルトポリシーが表示されています(DROP)。
2行目がカラム名です。

target: target名
prot: プロトコル名。例えば、tcp, udp, icmp, or all
opt: めったに使われません。
source: 接続元のIPアドレス or サブネット or anywhere
destination: 接続先のIPアドレス or サブネット or anywhere

iptablesコマンドの使い方

いくつかの例を紹介します。

特定のサーバーからのhttp通信を許可する

1
2
3
# iptables -A INPUT -p tcp -s 192.168.1.1 --dport 80 -j ACCEPT
# 設定を保存
# service iptables save

ルールを消す

iptables -D ルール で消すことができます。
iptables -S でルール一覧がでるので、そのルールを指定すれば簡単です。

1
2
# iptables -S
-A INPUT -s 157.7.105.69/32 -p tcp -m tcp --dport 80 -j ACCEPT

以下のコマンドで消します。

1
iptables -D INPUT -s 157.7.105.69/32 -p tcp -m tcp --dport 80 -j ACCEPT

参考文献

知っていると便利なRubyの小技集

a-zの文字列を作成する

1
2
('a'..'z').to_a.join
=> "abcdefghijklmnopqrstuvwxyz"

特定のkeyのみ抽出する

特定のkeyのみ抽出するにはvalues_atメソッドを使います。

1
2
h = { "cat" = "feline", "dog" = "canine", "cow" = "bovine" }
h.values_at("cow", "cat")  #=> ["bovine", "feline"]

keyとvalueの配列からhashを作成する

1
2
3
4
keys   = ["suzuki", "itou", "yamada"]
values = [87, 76, 69]
ary = [keys, values].transpose
h = Hash[*ary.flatten]

特定の範囲の要素を取得する

1
2
["a", "b", "c", "d", "e"][0..2]
=> ["a", "b", "c"]

配列からnilを取り除く

1
2
[1, 2, nil, 3, 4, nil].compact
=> [1, 2, 3, 4]

配列から特定の条件に一致する要素を取り除く

1
2
[1,2,3,4,5,6].delete_if { |x| x % 2 == 0 }
=> [1, 3, 5]

10進数を基数変換する

1
2
3
4
5
6
255.to_s(2)
=> "11111111"
255.to_s(8)
=> "377"
255.to_s(16)
=> "ff"

逆の操作を行う場合はto_iメソッドを使います。

1
2
3
4
5
6
"11111111".to_i(2)
=> 255
"377".to_i(8)
=> 255
"ff".to_i(16)
=> 255

ハッシュのvalueでソートする

1
2
3
scores = { 'Carol' => 90, 'Alice' => 50, 'Bob' => 60, 'David' => 40 }
scores.sort {|(k1, v1), (k2, v2)| v2 <=> v1 }
=> [["Carol", 90], ["Bob", 60], ["Alice", 50], ["David", 40]]

同じ値を数える

1
2
["a", "b", "c", "a", "b", "b"].each_with_object(Hash.new(0)) {|r, arr| arr[r]+=1 }
=> {"a"=>2, "b"=>3, "c"=>1}

LATEXチートシート - 数式記号の読み方・表し方

LATEXを使った数式記号の読み方・表し方をまとめました。
数式記号の読み方・表し方の数式を実際にLATEXで表示しています。

1. 数と式

記号 読み方 LATEX表記
aかけるb a \times b
a割るb a \div b
aプラスマイナスb a \pm b
aかけるb a \times b
a割るb a \div b
aプラスマイナスb a \pm b
aマイナスプラスb a \mp b
aかけるb a \cdot b
a小なりb
aはbより小さい
a < b
a大なりb
aはbより大きい
a > b
a小なりイコールb
aはb以下
a \leqq b
a大なりイコールb
aはb以上
a \geqq b
aはbと等しくない
aノットイコールb
a \neq b
aニアリーイコールb
aはbにほぼ等しい
a \fallingdotseq b
aのn乗 a^n
aのm乗のn乗 ( a^m ) ^n
ルートa
平方根a
\sqrt{a}
n乗根a \sqrt[n]{a}
a分のb
b割るa
\frac{b}{a}
絶対値a
aの絶対値
\mid a \mid
xを越えない最大の整数
ガウスx
[x]
a,b,c,… a,b,c,\cdots

2. 関数・写像

記号 読み方 LATEX表記
yイコールf,x
yイコールf,かっこ,x,(かっこ)
y=f(x)
f,インバースx
f,xの逆関数
f ^{-1} (x)
サインx \sin x
コサインx \cos x
タンジェントx \tan x
サイン2乗x \sin ^2 x
ログa,b
aを底数とするbの対数
\log _a x
ログ,x \log x
fマルg
fとgの合成写像
f \circ g
fインバース
fの逆写像
f ^{-1}
XからYへの写像f
X矢印,Y,f
X \stackrel{f}{\to} Y
aをbに移す写像f
a矢印,b,f
a \stackrel{f}{\to} b
xからyへの写像f
f,x矢印,y
f: x \to y
f,x,y
f,かっこ,x,y,(かっこ)
f(x,y)

3. ベクトル・行列

記号 読み方 LATEX表記
ベクトルa
aベクトル
\vec{a}
ベクトルAB
ABベクトル
\overrightarrow{AB}
ベクトルaの大きさ
ベクトルaの絶対値
\mid \vec{a} \mid
零ベクトル
ゼロベクトル
\vec{0}
ベクトルaはベクトルbではない \vec{a} \neq \vec{b}
ベクトルa,bは平行
ベクトルa平行ベクトルb
\vec{a} \parallel \vec{b}
ベクトルa,bは垂直
ベクトルa垂直ベクトルb
\vec{a} \perp \vec{b}
ベクトルaイコールa1,a2
ベクトルaイコール,かっこa1,a2
\vec{a}=(a_1,a_2)
ベクトルa,bの内積 \vec{a} \cdot \vec{b}
行ベクトルa,b
かっこ,a,b,
( a \quad b )
列ベクトルa,b
かっこ,a,b,
\begin{pmatrix} a \ b \end{pmatrix}
m,n行列
mかけるn行列
m \times n
行列a,b,c,d
かっこ,a,b,c,d
\begin{pmatrix} a & b \ c & d \end{pmatrix}
Aの2乗 A^2
Aの逆行列
Aインバース
A^{-1}
Aベクトルx A \vec{x}
零行列 O

4. 微分・積分

記号 読み方 LATEX表記
数列an { a_n }
シグマ,ak,k=1からnまで
シグマ,k=1からnまで,ak
\sum _{k=1} ^{n} {k(k+1)}
n矢印無限大
n無限大
n \to \infty
nが限りなく大きくなるときのanの極限値はα
リミット,n→∞,an,イコールα
\lim {n \to \infty} a_n=\alpha
x矢印a
xが限りなくaに近づく
x \to a
xが限りなくaに近づくとき,f(x)の極限値はbである
リミット,xがaに近づくときのf(x),イコール,b
リミット,x矢印a,f(x),イコールb
\lim {x \to a} f(x)=b
xがaに近づくときのf(x)の右極限値
リミット,xが大きい方からaに近づくときのf(x)
リミット,x矢印a+0,f(x)
\lim {x \to a+0} f(x)
xがaに近づくときのf(x)の左極限値
リミット,xが小さい方からaに近づくときのf(x)
リミット,x矢印a-0,f(x)
\lim {x \to a-0} f(x)
デルタx矢印0
デルタxが限りなく0に近づく
\Delta x \to 0
f,ダッシュ,x f’(x)
y,ダッシュ y’
dy,dx \frac{dy}{dx}
d,dx,f(x) \frac{d}{dx} f(x)
d,dx,f(x) \frac{d}{dx} f(x)
開区間a,b ( a,b )
閉区間a,b [ a,b ]
f,トゥーダッシュ,x f”(x)
y,トゥーダッシュ y”
d,トゥー,y,d,x,トゥー yの第2次導関数 \frac{d^2y}{dx^2}
f(x) d,トゥー,d,x,トゥー,f(x)
f(x)の第2次導関数
\frac{d^y}{dx^2} f(x)
yの第n次導関数 y^{(n)}
f(x)の第n次導関数 f^{(n)(x)}
d,n,d,x,n,f(x)
yの第n次導関数
\frac{d^ny}{dx^n}
d,n,d,x,n,f(x)
f(x)の第n次導関数
\frac{d^n}{dx^n} f(x)
インテグラル,aからbまで,f(x),dx \int _a ^b f(x) dx
F(x),a,b [ F(x) ] ^b _a

5. 集合・理論

記号 読み方 LATEX表記
AはBの真部分集合である A \subset B
AはBを真部分集合に持つ A \supset B
A含まれるB
AはBの部分集合である
AはBに含まれる
A \subseteqq B
A含むB
AはBを含む
BはAを部分集合に持つ
A \supseteqq B
aはAの要素である
aはAに属する
a属するA
a \in A
aはAの要素でない
aはAに属さない
a属さないA
a \notin A
aを要素とする
Aの要素
A \ni a
集合1,2,3,4
1,2,3,4を要素とする集合
{ 1,2,3,4 }
x(の集合)ただしx<6
x<6を満たす集合
{ x \mid x<6 }
AキャップB
A 交わり
AとBの交わり(共通部分)
AインターセクションB
A \cap B
A カップ B
A結びB
AとBの結び
AユニオンB
A \cup B
AイコールB
AはBに等しい
A=B
Aバー
Aの補集合
\bar{A}
空集合
ファイ
\phi
PならばQ P \Rightarrow Q
PとQは同値 P \Leftrightarrow Q
Pでない
Pの否定
Pバー
\bar{P}

6. 確率・統計

記号 読み方 LATEX表記
n,P,r
Pのn,r
パーミュテーション,n,r
_n P _r
n,C,r
Cのn,r
コンビネーション,n,r
_n C _r
nの階乗
nファクトリアル
n!
n,A
n,かっこ,A,(かっこ)
n(A)
P,A
事象Aの確率
P(A)
P,A,B
PのA,B
P,A,かっこ,B,(かっこ)
P _A (B)
xバー
xの平均
\bar{x}
E,X
Xの平均
E(X)
V,X
Xの分散
V(X)
シグマ,X
Xの標準偏差
\sigma (X)
P,かっこ,X=a,(かっこ)
X=aとなる確率
P(X=A)
B,n,p B(n,p)
N,m,σ2 N(m,\sigma ^2)

7. 幾何

記号 読み方 LATEX表記
x度 x \circ
角A \angle A
三角形ABC \triangle {ABC}
l平行m
lとmは平行
l \parallel m
lとmは平行でない l \nparallel m
△ABCと△DEF合同
△ABC合同△DEF
\triangle {ABC} \equiv \triangle {DEF}
ABの長さ
ABのバー
\overline{AB}

8. ギリシャ文字

記号 読み方 LATEX表記
アルファ \alpha
ベータ \beta
ガンマ \gamma
シータ \theta
パイ \pi
デルタ \Delta

参考リンク