2016 講義ノート・メモ
Table of Contents
- 1. ruby のノート
- 1.1. Ruby紹介
- 1.2. Rubyの原理
- 1.3. 言語上のこと
- 1.4. クラスとは
- 1.5. クラス・モジュールの概念
- 1.6. プログラムで見る Rubyの原理
- 1.7. メタプログラミング Ruby のノート
- 1.8. test-unit
- 1.9. プログラミングの課題
- 1.10. sqlite3-ruby
- 1.11. org-doc web service
- 1.12. クラスライブラリの抜粋
- 2. memo
- 2.1. memo
- Doing test-unit
- Doing poker.org
- global
- ソースコード解説
- ソースコード pry-doc
- EmacsでPATHの設定が引き継がれない問題をエレガントに解決する - Qiita
- gem install spreadsheet for meta-ruby
- meta-ruby 講義内容
- Done .ob org-mode #+babel_include の導入 include babel org
- Doing org-tangle auto tangle babel org
- new org-mode babel-include を展開する
- ruby 日本語
- ruby入門のサイトを変更したい
- org babelを調べる
- meta-ruby
- Rubyを勉強する上で有用な情報源まとめてみた - Qiita
- ob-ruby
- 若手エンジニア/初心者のためのRuby 2.1入門(12):難しいが強力! Rubyのメタプログラミング、self、特異クラス/メソッド、オープンクラスとモンキーパッチ (1/4) - @IT
- Ruby - 【mkdirからデプロイまで3分】Sinatra+Haml+Sass+Coffee でサクッとHerokuに公開して捨てるwebアプリ - Qiita
- emacs-24.5 for @cis.iwate-u.ac.jp
- ~/bin/org2html index.org
- Todo ditaa@github install後,ditaa.jar が見つからない
- log new_file graphviz
- Emacs org-modeを使ってみる: (19) graphvizとditaaの図を埋め込む - 屯遁のパズルとプログラミングの日記
- memo lstree directory
- org2HTMLの自動化
- 2.1. memo
ホーム / 講義 / ruby / OO / poker開発 / emacs / meta-ruby / note / github-repos / svn-repos 2015 /
1 ruby のノート
1.1 Ruby紹介
はじめに
- Rubyは手軽なオブジェクト指向プログラミングのためのインタプリタ言語
- Rubyはテキスト処理やシステム管理のための豊富な機能を持っています。
- Rubyは単純で、分かりやすく、簡単に拡張できます。
Rubyの特長
インタプリタ
Rubyはインタプリタ言語です。プログラムを実行するためにコンパイル する必要はありません。
変数に型が無い (動的型付け)
Rubyの変数はどのような型のデータも格納する事ができますので、 変 数の型について心配する必要はありません。 半面、コンパイル時のチェッ クは弱くなります。
変数宣言が不要
Rubyでは変数を宣言無しで使う事ができます。 変数の種類(ローカル変 数、グローバル変数、インスタンス変数など)は 変数名から知る事がで きます。
単純な文法
Rubyの文法はEiffelからわずかに影響を受けた単純なものです。
ユーザによるメモリ管理が不要
Rubyはメモリ管理を自動的に行います。 どこからもアクセスされなく なったオブジェクトは インタプリタに組み込みのガーベージコレクタ によって回収されます。
全てがオブジェクト
Rubyははじめから純粋なオブジェクト指向言語として設計されています。 整数のような基本的なデータ型をはじめとして、 全てのデータをオブ ジェクトとして統一的に取り扱えます。
クラス、継承、メソッド
Rubyは クラス、継承、メソッドのようなオブジェクト指向言語として 基本的な機能は 当然持っています。
特異メソッド
ある特定のオブジェクトにメソッドを付加することができます。 たと えば、GUIのあるボタンを押された時の動作を メソッドとして記述する ような使い方ができますし、 これを応用してプロトタイプベースの オ ブジェクト指向プログラミングも可能です(やりたければね)。
モジュールによるMix-in
Rubyは多重継承は複雑さの源であるという見地から、 意図的に多重継 承を持っていませんが、 モジュールを使ってクラス階層を横断して実 装を共有できます。 この機能を"Mix-in"と呼びます。
ブロック付きメソッド呼び出し(イテレータ)
制御構造の抽象化を援助するブロック付きメソッド呼び出しという機能があります。
クロージャ
手続きをオブジェクトとして扱う機能があります。 このオブジェクト 化された手続きのことをクロージャと呼びます。
強力な文字列操作/正規表現
Perlをお手本とした強力な文字列操作や正規表現検索の機能があります。
多倍長整数
組み込みの多倍長整数機能がありますので、 メモリが許す限り、非常 に大きな整数の演算もできます。 たとえば、400の階乗なども簡単に計 算できます。
例外処理機能
例外処理機能は例外的な状況への対処が簡単に書けます。
OSへの直接アクセス
Rubyは(UNIXの)ほとんどのシステムコールの呼び出し機能を持っていま す。 Rubyだけでシステムプログラミングも可能です。
ダイナミックローディング
OSが許せば、オブジェクトファイルを実行時に読み込む機能が提供され ます。
1.2 Rubyの原理
- 原典: オブジェクト (ruby-lang.org)
- 原典: クラス (Ruby 2.0.0)
オブジェクト
ここに,ruby の基本原理, が書かれていると,((s-:)) は思う。
オブジェクトとは
- Ruby で扱える全ての値はオブジェクトです。
- Rubyのオブジェクトに対して可能な操作はメソッド呼び出しのみです。
- あるオブジェクトが反応できるメソッドは、 そのオブジェクトが所属するクラスによって一意に決定します。
- 所属するクラスはオブジェクト生成時に決まり、その後は特異クラスの導入 以外、所属クラスが変わることはありません。
- またオブジェクトは、特定のクラスに対比して、その「インスタンス」とも呼ばれます。
- オブジェクトの生成は、一般には、別のオブジェクトのメソッドを呼び出すことによって行われます。
クラス
- クラスは自身に所属するオブジェクトが反応できるメソッドを決定します。
- 所属するオブジェクトに対してあるメソッドを呼び出すことができるなら、 そのメソッドが「クラスに定義されている」と言います。
- またメソッドはクラスとメソッド名によって一意に決定します。
- クラスは必ずただひとつの「スーパークラス」を持ち、
- スーパークラスであるメソッドが定義されていれば自クラスでもそのメソッ ドが同じ内容で定義されていることになります。 これを「継承」と呼びます。
- 継承は推移するので、スーパークラスのスーパークラスが持つメソッドもま た自クラスにおいて定義されていることになります。
モジュール
- ちょっと特殊でクラスではない。しかし機能は同じ。
メソッド
- メソッドは実行することができます。その実行を開始することを通常「呼び 出す」と言います。
- また呼び出すときにはオブジェクトを渡すことができ、そのオブジェクトを 「引数」と呼びます。
- いくつの引数を受け取ることができるかはメソッドの定義時に決定し、変更 することはできません。
Todo クラス
クラスとオブジェクト
- Ruby プログラムからはクラスもまたオブジェクトとして扱うことができる。
- 以下の基本操作が可能:
- メソッドの存在を問い合わせる
- メソッドを定義する
- メソッドの定義を取り消す
モジュール
- Ruby プログラムからはクラスもまたオブジェクトとして扱うことができる。
- 以下の基本操作が可能:
- メソッドの存在を問い合わせる
- メソッドを定義する
- メソッドの定義を取り消す
クラスと同じだが,インスタンスを作ること,はできない。
特異クラス
あるオブジェクトだけに定義されたクラス (by ((s-:)))
1.3 言語上のこと
変数と定数 (Ruby 2.0.0)
変数 https://www.rubylife.jp/ini/var/ 変数 - Ruby入門
変数への代入
変数への代入
変数 ~ 値
多重代入 : 変数1, 変数2, 変数3 ~ 値1, 値2, 値3
x1 ~ 10 x1, x2, x3 ~ 1, 2, 3 x1, x2, x3 ~ [1, 2, 3] 'end'
変数の種類
https://docs.ruby-lang.org/ja/2.0.0/doc/s 変数と定数 (Ruby 2.0.0)
- グローバル変数
- ローカル変数
- インスタンス変数
- クラス変数
- 定数
Ruby予約語
: BEGIN class ensure nil self when : END def false not super while : alias defined? for or then yield : and do if redo true : begin else in rescue undef : break elsif module retry unless : case end next return until
変数名としては使用できません。
- 自己代入
- 多重代入
スコープ
講義後半で説明します。
Block/Module
- ローカル変数
- グローバル変数
Object
- インスタンス変数
Class
- クラス変数
Module/Class (?) - ((自信なし))
- 定数
Rubyにおけるトップレベル
トップレベル
print("Hello¥n") 'end'
クラス定義の外側の部分はトップレベルと呼ばれています。
ruby が実行されると, トップレベルに記述されたプログラムが順に実行 されて行きます。
selfとmain
self 'end'
では「main」と言うオブジェクトの元になっているクラスは何かを確認し てみます。オブジェクトに対して「class」メソッドを実行するとそのオ ブジェクトをのクラスを返します。
self self.class 'end'
「main」オブジェクトの元になっているクラスは「Object」クラスと表示 されます。
トップレベルに定義されたメソッド
ップレベルの中にもメソッドを定義することが出来ます。
トップレベルに定義されたメソッドは*「Kernel」モジュール*の中に追加 されることになっています。
「Kernel」モジュールは全てのクラスの元になっている「Object」クラス に読み込まれています。
その為、トップレベルに定義されたモジュールは、「Kernel」モジュール の中で既に定義されている「print」メソッドなどと同じようにどのクラス 内からでも呼び出すことができます。
またメソッドを呼び出す際に、呼び出し元のオブジェクト(レシーバーと呼 ばれています)を省略できるので、あたかも関数のように使用することが可 能です。
よって特定のクラス内ではなくトップレベルの位置にメソッドを定義すれ ば、関数のように使用できるメソッドを定義することが可能となります。
メソッドの定義と呼び出し
def メソッド名(引数1, 引数2, ...) 実行する処理 実行する処理 end
public (def printHello print("Hello\n") end).class printHello self.printHello 'end'
メソッドの呼び出し
定義されたメソッドを呼び出すと、処理がメソッド内に移りメソッド内に 記述された処理が実行されます。そしてメソッドの最後まで処理が終わる と、メソッドを呼び出した次の行へ処理が戻ります。
メソッドを呼び出す時の書式は次の通りです。
オブジェクト.メソッド名(引数1, 引数2, ...)
メソッドはクラス内で定義され、そのクラスから作成されるオブジェクト (レシーバーと呼ばれます)に対して行わせたい処理を記述するものです。 その為、メソッドを呼び出す時には対象となるオブジェクトと実行させる メソッド名を指定して呼び出します。
メソッド名(引数1, 引数2, ...)
では定義されたメソッドを呼び出してみます。
メソッド定義の位置
メソッドは実際に呼び出されるよりも前に定義されていなければなりませ ん。例えば次のようなプログラムはエラーとなります。
上記のようにメソッド呼び出しがメソッドの定義よりも前に実行されると 「undefined local variable or method」と言うエラーが表示されます。
x 'end'
引数を付けたメソッド呼び出し
引数のデフォルト値
通常引数は呼び出し側とメソッド定義側で数が一致している必要がありますが、メソッ ド定義側では引数にデフォルト値を設定することが可能です。書式は次の通りです。
def メソッド名(変数1~デフォルト値1, 変数2~デフォルト値2, ...) 実行する処理 実行する処理 end
def printHello(msg~"No msg", name~"No name") print(msg + "," + name + "¥n") end printHello("Hello", "Yamada") printHello("Hello") printHello() def printHello(msg, name~"No name") print(msg + "," + name + "¥n") end printHello("Hello", "Yamada") printHello("Hello") 'end'
引数を配列として受け取る
メソッドの戻り値
多重代入を使って複数の戻り値を取得
文字列オブジェクト
String.new("こんにちは\n") "こんにちは\n" "こんにちは\n".class String.class 'end'
バックスラッシュ記法によるエスケープ
%Q、%qによる文字列の作成
require 'kconv' print Kconv.toutf8(%Q[こんにちは"佐藤"さん\nお元気ですか]), "\n" print Kconv.toutf8(%q|こんにちは\nお元気ですか|), "\n" 'end
ヒアドキュメントによる複数行文字列の作成
文字列の中に式を展開
name ~ "東京" print("出身は #{name*10} です") 'end'
便利で,よく使います。
文字列 methods
1.4 クラスとは
クラスとオブジェクト
- クラス*は *オブジェクト の設計図です。
- オブジェクトはクラスから生まれる
- 具体化 (instantiate)
- オブジェクトはクラスの インスタンス (instance)
- オブジェクトの処理を記述するのが*メソッド*
- クラス定義の中に記述する.
- オブジェクト 毎 の状態を保持するのが インスタンス変数
- (instance) メソッドの実行
- 自分の状態 (instance)
class Car … end
class は Carクラスから生まれるオブジェクトの振舞を記述する。
class Car def initialize(carname) @name ~ carname end def dispName print(@name) end end car ~ Car.new("crown") car.dispName 'end'
「車」の設計図であるクラスを定義し、
: class Car … end
クラスからオブジェクトを作成した後で、
car ~ Car.new
オブジェクトに対して名前を画面に出力させる
car.dispName
インスタンスメソッド
クラス内に記述されたメソッドはクラスから作成されたオブジェクトしか 呼び出すことが出来ません。このようなメソッドを インスタンスメソッ ド と呼びます。
class クラス名 def メソッド名(引数1, 引数2, ...) 処理 end end 'end'
例えばクラス名について表示するだけの簡単なインスタンスメソッドは次のようになり ます。
class Car def dispString(str) print(str, "¥n") end end 'end'
なお、引数が無いメソッドの場合は括弧を省略しても構いません。
class Car def dispClassname print("Car class¥n") end def dispString(str, "¥n") print(str) end end 'end'
インスタンスメソッドの呼び出し
定義されたインスタンスメソッドはクラスのオブジェクトから呼び出すことができます。
class Car def dispClassname print("Car class¥n") end
def dispString(str, "¥n") print(str) end end
car ~ Car.new car.dispClassname car.dispString("crown")
オブジェクトからメソッドを呼び出すにはオブジェクトの後にドット「.」を付けてメ ソッドを名を記述します。引数がある場合は括弧の後に引数をカンマで列挙して記述し て下さい。引数が無い場合はメソッド名だけで結構です。
オブジェクト名.メソッド名(引数1, 引数2, …) オブジェクト名.メソッド名
またドット「.」の代わりにコロン(:)を2つ続けて次のように記述することも出来ます。
オブジェクト名::メソッド名(引数1, 引数2, …) オブジェクト名::メソッド名
どちらの形式も違いはありませんので、どちらかに統一して利用すればいいと思います。
オブジェクトを作成する為に使用した「new」メソッドはクラスに対して実行しました。 例えば「Car.new()」のようにです。このようなメソッドはクラスに対して実行するク ラスメソッドと呼ばされます。今回のようにクラス内に定義したインスタンスメソッド はクラスから作成したオブジェクトに対して実行する点が異なっていることに注意して 下さい。
サンプルプログラム
では実際に試してみます。
ClassTest3.rb
class Car def dispClassname print("Car class¥n") end
def dispString(str) print(str, "¥n") end end
car ~ Car.new() car.dispClassname car.dispString("crown")
上記を実行すると次のように表示されます。
インスタンスメソッド
今回は2つのインスタンスメソッドを定義し、クラスから作成したオブジェクトに対し てメソッドを実行してみました。
class Reji SHOUHIZEI ~ 0.05 def initialize(init~0) @sum ~ init end def kounyuu(kingaku) @sum +~ kingaku end def goukei() return @sum * (1 + SHOUHIZEI) end end 'end'
reji ~ Reji.new(0) reji.kounyuu(100) reji.kounyuu(80) print(reji.goukei()) 'end'
SHOUHIZEI class \Reji print SHOUHIZEI end Reji::SHOUHIZEI 'end'
継承
class Car def accele print("アクセルを踏みました") end def brake print("ブレーキを踏みました") end end 'end'
a ~ Car.new("abc") a.brake 'end'
class Soarer < Car def initialize(name,type) @type ~ type super(name) end def openroof print("open roof\n"); end end class Crown < Car def reclining print("reclining") end end 'end'
so ~ Soarer.new("soarer") cr ~ Crown.new("crwon") so.class (so.class).superclass so.dispName 'end'
\
#<Soarer:0x007fb02b61d888 @name~"soarer"> #<Crown:0x007fb02b616ec0 @name~"crwon"> Soarer Car soarernil
1.5 クラス・モジュールの概念
- origin: クラス・モジュールの概念 Ruby - Qiita
ここでクラスとモジュールの概念について学ぶ。
例 Panda モジュール
module Panda def visit_to_Japan "Mr.TonTon" end def panda @panda ~ "panda" end end 'end'
Pandの型,Pandが受け継いでいる型は何でしょう?
Panda.class ## Pandaの型 Panda.ancestors ## Panda型の階層 'end'
Panda は Moduleクラスのオブジェクト, Pand ~ Module.new
module Panda; … ;end は,Panda のトップレベルを開いて, 実行すること。
Panda.new 'end'
Panda.new とかはできない
module Panda def panda @panda ~ "panda" end end 'end'
Panda.pand 'end'
Panda.instance_methods(false) 'end'
module Panda; def m ; end
つまり,Panda にメソッドを定義できる。
module Panda; CONST ~ 'panda const'; end Panda::CONST CONST
つまり,Panda は名前空間。
定数 Module
Module の class は Class, つまり Module は Classクラスのオブジェクト, つまりクラス
Module.new で Module型のオブジェクト(モジュール)を作る
例 Zooクラス
class Zoo def the_zoo "there are lots of animal" end end 'end'
## Zooの型 Zoo.class (Zoo.class).ancestors ## Zoo型の階層 Zoo.ancestors ## クラス? Zoo.new 'end'
Zoo は Classクラスのオブジェクト, Zoo ~ Class.new
class Zoo; … ; end は, Zoo のトップレベルを開いて,実行すること
Zoo.new ができる。Zoo.class の ancestors に Class が入っているから
例: UenoZoo を Zoo を継承して作る
class UenoZoo < Zoo # Zooクラスの継承 include Panda # Pandaモジュールを mix-in def monkey @monkey ~ "monkey" end def elephant @elephant ~ "elephant" end def lion @lion ~ "lion" end def self.name # UenoZooクラスの特異メソッド "Ueno Zoo" end end
(UenoZoo.class).ancestors UenoZoo.ancestors UenoZoo.new 'end'
説明
mix-in
モジュールをクラスに取り込む事をmix-inといい、ソフトクリームの上に 載せるトッピングがその名の由来。
継承
Rubyのクラスは継承ができ、親のクラスのインスタンスメソッドを子が受け継ぐ。 1つのクラスに二つ以上のクラスは継承ができなく、これを単純継承という。
継承とMix-in
上記のコードはUenoZooクラスはZooクラスのメソッドを継承している。またUenoZooク ラスはPandaモジュールをmixinしている。
Zooクラスで定義されているインスタンスメソッドはUenoZooクラスで使えて、Pandaモ ジュールをインクルードすることによって、Zooクラスでインスタンスメソッドとして 使う事ができる。
extend
モジュールはクラスの使い方にバリエーションを与える。
もしModuleをクラスメソッドとして定義したい場合は extend を使用する 事によって使う事ができる。
class UenoZoo extend Panda end
(UenoZoo.class).ancestors UenoZoo.ancestors UenoZoo.singleton_methods UenoZoo.singleton_class UenoZoo.new 'end'
UenoZoo.visit_to_Japan UenoZoo.name UenoZoo.panda 'end'
また prepend を使えば継承関係を一番手前にしてモジュールにあるメソッドにsuperを 使ってオーバーライド(メソッド上書き)できるようになる、Railsのコントローラーで 使われるbefore actionのような機能を実装できる。 super メソッドは継承されているクラスのメソッド、もしくはモジュールでmixinされ たメソッドで同名のメソッドを呼ぶ事ができるメソッド。
module Panda
def visit_to_Japan super + " and " + "Mr.TonTon" end
def panda @panda ~ "panda" end end
class UenoZoo < Zoo prepend Panda def monkey @monkey ~ "monkey" end
def elephant @elephant ~ "elephant" end
def lion @lion ~ "lion" end
def self.name "Ueno Zoo" end
end
> UenoZoo.ancestors
~> [Panda, UenoZoo, Zoo, Object, Kernel, BasicObject]
UenoZoo.new.visit_to_Japan
~> "Mr.RanRan and Mr.TonTon"
ちなみにクラスにはinitializeメソッドという便利なメソッドが定義されている。 このメソッドはオブジェクトが作成された時に呼ばれるメソッドである。
例えば、上のコードでmonkeyメソッドとelephantメソッドとlionメソッドはインスタン ス変数を定義してメソッドに格納しているが下記のメソッドのようにすれば短くなる。
class UenoZoo def initialize(monkey~"monkey", elephant~"elephant", lion~"lion") @monkey ~ monkey @elephant ~ elephant @lion ~ lion end end UenoZoo.new.instance_variables ~> [:@monkey, :@elephant, :@lion]
このままだとメソッドで変数を呼び出せないので, attr_readerを使う。
class UenoZoo attr_reader :monkey, :elephant, :lion def initialize(monkey~"monkey", elephant~"elephant", lion~"lion") @monkey ~ monkey @elephant ~ elephant @lion ~ lion end end UenoZoo.new.monkey ~> "monkey" Ueno.new.monkey ~ "pokey" ~> undefined method `monkey~' for #<UenoZoo:0x007fa782157008> (NoMethodError)
ただこのメソッドは格納したインスタンス変数を呼び出す機能しかないので、 書き込み機能も加えるためにattr_accessorを使う。書き込みのみの場合は attr_writerを使う。
class UenoZoo attr_accessor :monkey, :elephant, :lion def initialize(monkey~"monkey", elephant~"elephant", lion~"lion") @monkey ~ monkey @elephant ~ elephant @lion ~ lion end end UenoZoo.new.monkey ~> "monkey" Ueno.new.monkey ~ "pokey" ~> "pokey"
モジュールの使い方
2種類ある
- メソッドの格納庫として使う
- 名前空間として使う
名前空間としての使い方
同じクラスを定義して、既存のメソッドとは知らずに新たに定義し直して、将来 的なバグに繋がる可能性になる。
またクラス名とモジュール名は定数で定義されていて、 module名で定義された定数はclass名で定義できない。 その場合は名前空間として使う。下記のコードを参照してほしい。
class Cat def tuna "delicious" end end module Zoo class Cat def tuna "delicious" end end end > Zoo::Cat.new.tuna ~> "delicious" > Cat.new.tuna ~> "delicious"
CatクラスとZoo::Catクラスは別々のオブジェクトになる。module名と class名は定数だが定数の中から定数を呼ぶ場合はコロンを二個つけて:: で呼び出す。
まとめ
クラスはインスタンス化能力をもちメソッドを定義できる、モジュールは インスタンス化能力を持たないがメソッドを格納できる。モジュールの利 用法はメソッドを格納するか名前空間として利用する。
クラスにモジュールを取り込むことをmixinといってincludeを使う。
またクラスメソッドとして取り込む場合はextend、継承関係に着目して取 り込む場合はprepend。attr属性(attr_accessor, attr_writer, attr_reader)を使えば、そのクラスに属性を与えられる。initializeメソッ ドを使えば、オブジェクトが生成された時に値を格納したりする事ができ る。
モジュールの先祖
module GiantPanda end 'end'
module GiantPanda include Panda end 'end'
(GiantPanda.class).ancestors GiantPanda.ancestors 'end'
1.6 プログラムで見る Rubyの原理
クラス
- インスタンス化能力を持つ。
- インスタンスメソッドを格納できる。
- クラスもオブジェクトである。
- クラスメソッドを格納できる。
モジュール
- インスタンス化能力は持たない
- インスタンスメソッドを格納できる
- モジュールもオブジェクトである。
- クラスメソッドを格納できる
Class と Module
Class.class Class.ancestors C ~ Class.new C.class C.ancestors c ~ C.new c.class c.ancestors 'end'
定数 Class はクラス(クラス型のオブジェクト)である。
C ~ Class.new は,クラス(クラス型のオブジェクト)を生成する
[Class, Module, Object, Kernel, BasicObject]
- C.new は,オブジェクトを生成する
- Class と C では new の振る舞いは異なる
定数 Module はクラスでありクラス型のオブジェクトである。
- Module ~ Class.new(Object)
あるオブジェクト obj が クラス型であるとは, (obj.class).ancestors に Class が含まれること
クラス - モジュール
- インスタンス化能力
(Class.new).class (Module.new).class (Class.new).new (Module.new).new (Class.new).ancestors - (Module.new).ancestors (Class.new).ancestors (Module.new).ancestors (Class).ancestors - (Module).ancestors 'end'
memo コード
class 階層
1.class (1.class).superclass (1.class).superclass.superclass (1.class).superclass.superclass.superclass (1.class).superclass.superclass.superclass.superclass (1.class).superclass.superclass.superclass.superclass.superclass 'end'
1.methods (Object.new).methods (BasicObject.new).methods 'end'
- method メソッドはBasicObjectのインスタンス・メソッドではない
- method メソッドはObjectのインスタンス・メソッド
(1.class).ancestors (Object.instance_methods).include?(:methods) (Kernel.instance_methods).include?(:methods) (BasicObject.instance_methods).include?(:methods) 'end'
(1.class) ((1.class).class) ((1.class).class).superclass ((1.class).class).superclass.superclass ((1.class).class).superclass.superclass.superclass ((1.class).class).superclass.superclass.superclass.superclass :end
Class (Class.class) (Class.class).superclass (Class.class).superclass.superclass (Class.class).superclass.superclass.superclass (Class.class).superclass.superclass.superclass.superclass :end
Class Class Module Object BasicObject nil
Module (Module.class) (Module.class).superclass (Module.class).superclass.superclass (Module.class).superclass.superclass.superclass (Module.class).superclass.superclass.superclass.superclass :end
def class_hier(obj) if obj.superclass print " ~> ", obj.superclass class_hier(obj.superclass) end end
class_hier(Class) class_hier(Integer) 'end'
Class.singleton_class (Class.singleton_class).superclass (Class.singleton_class).superclass.superclass (Class.singleton_class).superclass.superclass.superclass (Class.singleton_class).superclass.superclass.superclass.superclass :end
(Class.singleton_class).singleton_class (Class.singleton_class).singleton_class.singleton_class :end
(Class.singleton_class).singleton_class (Class.singleton_class).singleton_class.superclass (Class.singleton_class).singleton_class.superclass.superclass (Class.singleton_class).singleton_class.superclass.superclass.superclass :end
Class.ancestors Module.ancestors (Class.new).ancestors (Module.new).ancestors 'end'
Class.singleton_class (Class.singleton_class).ancestors 'end'
self
self self.class class H $selfH ~ self def m $selfm ~ self puts "m is called." 'm' end end print "$selfH ~ ", $selfH h ~ H.new h.m print "$selfm ~ ", $selfm :end
methods
1.methods - (Numeric.new).methods Integer(1001) String("abc") Array(2) Array(1..100) Kernel.Array(2) self.Array(2) 'end'
Kernel.methods.include?(:Array) Kernel.methods.include?(:Integer) 'end'
1.7 メタプログラミング Ruby のノート
オブジェクトモデル
class定義
what_is_self_in_class_def ~ class MyClass CONSTANT ~ 'MyClassの定数' self end p what_is_self_in_class_def 'end'
irb(main):002:0* irb(main):003:1> irb(main):004:1> irb(main):005:1> ~> MyClass MyClass ~> MyClass
class MyClass
は,
- ~Class~型のオブジェクトを生成し,
- 定数
MyClass
にその値をセットし, - self を
MyClass
オブジェクトにし, - self のトップレベルで,
end
までの ruby 式を評価し,- 最後の式の値を返す。
class MyClass p CONSTANT KONSTANT ~ 'MyClassの別の定数' end p CONSTANT p MyClass::CONSTANT p MyClass::KONSTANT MyClass.constants 'end'
irb(main):012:1> irb(main):013:1> "MyClassの定数" ~> "MyClassの別の定数" NameError: uninitialized constant CONSTANT from (irb):14 from /home/staff/suzuki/.rbenv/versions/2.0.0-dev/bin/irb:11:in `<main>' "MyClassの定数" ~> "MyClassの定数" "MyClassの別の定数" ~> "MyClassの別の定数" ~> [:CONSTANT, :KONSTANT]
class MyClass
で,~MyClass~ (クラス)オブジェクトのトップレベルに入 る- ruby のクラスは変更に対し,開かれている (オープン・クラス)
- 定数~CONSTANT~ はMyClass の名前空間に定義されている
object のクラス階層
obj~ MyClass.new obj.class (obj.class).ancestors 'end'
~> #<MyClass:0x007fd4425309d0> ~> MyClass ~> [MyClass, Object, Kernel, BasicObject]
objの型
クラスのクラス階層
MyClass.class (MyClass.class).ancestors 'end'
~> Class ~> [Class, Module, Object, Kernel, BasicObject]
MyClassのオブジェクトとしての型階層
メタクラスのクラス階層
MyClass.singleton_class (MyClass.singleton_class).ancestors 'end'
~> #<Class:MyClass> ~> [#<Class:MyClass>, #<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]
MyClassのオブジェクトとしての型階層
特異クラスと特異メソッド
特異メソッド
あるオブジェクトにだけ実行できるメソッドを定義できる:
obj1 ~ Object.new obj2 ~ Object.new def obj1.m "obj's singleton method" end obj1.m obj2.m obj1.methods.include?(:m) obj2.methods.include?(:m) 'end'
~> #<Object:0x007f5711dd60e8> ~> #<Object:0x007f5711daf420> irb(main):004:1> irb(main):005:1> ~> :m irb(main):007:0* ~> "obj's singleton method" NoMethodError: undefined method `m' for #<Object:0x007f5711daf420> from (irb):8 from /home/staff/suzuki/.rbenv/versions/2.0.0-dev/bin/irb:11:in `<main>' irb(main):010:0* ~> true ~> false
m
は何処にあるか?
- obj1とobj2 の
class
は,Object. class
はリンク。- obj1 から Object へのリンクの途中に在る
obj1.class obj1.singleton_class (obj1.singleton_class).class (obj1.singleton_class).instance_methods(false) 'end'
~> Object ~> #<Class:#<Object:0x007f5711dd60e8>> ~> Class ~> [:m]
m
の居場所は,#<Class:#<Object:0x007f5711dd60e8>> 特異クラス
'end'
MyClass.ancestors.each do |k| if k.singleton_class print k, ": ", (k.singleton_class).instace_methods, "\n" 'end'
test class hier
def find_instance_method(klass, method) prev ~ nil klass.ancestors.each do |k| break unless k.instance_methods.include?(method) prev ~ k end return prev end def find_singleton_method(klass, method) prev ~ nil klass.ancestors.each do |k| break unless k.instance_methods.include?(method) prev ~ k end return prev end find_instance_method(MyClass,:constants) find_singleton_method(MyClass,:constants) find_instance_method(Kernel,:constants) find_singleton_method(Kernel,:constants) find_instance_method(Module,:constants) find_singleton_method(Module,:constants) 'end'
method
method_missing
- メソッド が class 階層中にない時,
- missing_method が呼ばれる
- class 階層中に missing_method がない時,
- エラーになる
動的methodの仕組み
- 動的定義 define_method (:method_id) block
- 動的呼び出し send("method", *args)
method_missing(method, *args)の利用
- 動的に未定義のメソッドと引数が取得できる
- 他のメソッドへ委譲したり (動的proxy)
- メソッドを on-demand で定義できたり (ghost method) openstruct
最終形
様々なComputer の様々な付属品を扱う多種のデータベースへのアクセス を簡単にする:
ブロック
この章で理解すべきこと
- スコープ
- クロージャ
- クロージャによるスコープの操作
- 呼び出し可能オブジェクトへの変換
ブロックの基本
ブロックの作成
- do … end が block
- メソッド呼び出しの時のみ
ブロックが与えられているか?
- block_given? で調べられる
ブロックの呼び出し
- 呼ばれたメソッド側で yield により呼び出せる
- しかし,block は,block が作られた*環境*で実行される
クロージャ
コードの実行
- ブロックはコード
- self が実行の主体 (場)
self は 環境 を持つ
環境は,スコープ上の変数とその値のペア(束縛)の集まり
- 局所変数 (一方向) のスコープ
- block の入れ子構造 (nesting) のスコープ
- インスタンス変数 (一通り) のスコープ
- クラス変数 (一通り) のスコープ
- class の継承方向のスコープ
- 定数 (2方向)のスコープ
- module の入れ子構造 (nesting) のスコープ
- class の継承方向のスコープ
- 局所変数 (一方向) のスコープ
- クロージャ ~ block + self (環境)
- ブロックが生まれるとき,自身が生まれた環境を閉じ込めた ((クロージャ)) となる
- クロージャが実行される時は,その環境で実行される
- 定数はselfのクラスから辿れる
- インスタンス変数、特異メソッドには self から辿れる
スコープのまとめ
- Rubyのスコープには束縛がある
- スコープは class, module, def のスコープゲートで区切られ。
- スコープゲートは,Class.new(), Module.new(), Moduel#define_method() で置き換え,それらに束縛を閉じこめたクロージャを与える。
- クロージャにより,束縛の共有も可能となる
(s) この辺りは,SICP の lambda による実現の方が,シンプルでわかりや すい。
instance_eval()
- obj.instance_eval block
- オブジェクトobjのコンテキストで,
- ブロックblockを評価する
- (no term)
- obj を self にして, クロージャを実行するということ
カプセル化の破壊
instance_eval を使うとカプセル化が破壊できる
呼び出し可能オブジェクト
ブロックの使用
- コードの保管
- yieldを使ったブロックの呼び出し
コードを保管できる状況
- (({Proc})) の中.ブロックがオブジェクトになる
- (({lambda})) の中.
- メソッドの中
ブロックを Proc にする方法
- Proc.new()
- lambda { }
- &修飾
- Object#method() でメソッドを,Method オブジェクトとして取得可
- Method オブジェクトは,Method#call() で呼び出し可能
- Method オブジェクトは,属するオブジェクトのスコープで実行される
- Method#unbind() は属するオブジェクトを引き離し,UnboundMethod オブジェクトが返る
- UnboundMethodはMethod#bind()でメソッドに戻せる クラスが異なると,例外が発生
呼び出し可能オブジェクト [/]
[ ]
ブロック- オブジェクトではないが,呼び出し可能
- 定義されたスコープで評価される
[ ]
Proc- 定義されたスコープで評価される
- 定義されたコンテキストの制御にしたがう
[ ]
lambda- Proc クラスのオブジェクト,クロージャ
- 定義されたスコープで評価される
- 独立した method のように振る舞う
[ ]
メソッド- オブジェクトにつながれ,
- オブジェクトのスコープで評価される
1.8 test-unit
ruby/test
test-unit
install
gem install test-unit
テストの書き方
基本
- classで書く.
- TestCase毎に呼ばれる startup/shutdown
- Test毎に呼ばれる setup/teardown/cleanup
- テストは test で始まるメソッドで書く
require "rubygems" gem "test-unit" require "test/unit"
class TestSample < Test::Unit::TestCase
class << self # テスト群の実行前に呼ばれる.変な初期化トリックがいらなくなる def startup p :_startup end # テスト群の実行後に呼ばれる def shutdown p :_shutdown end end
# 毎回テスト実行前に呼ばれる def setup p :setup end # テストがpassedになっている場合に,テスト実行後に呼ばれる.テスト後の状態確認とかに使える def cleanup p :cleanup end # 毎回テスト実行後に呼ばれる def teardown p :treadown end
def test_foo p 'test_foo' assert_true(1 == 1) end def test_bar p 'test_bar' assert_equal(1, 1) end end
(defvar org-babel-ruby-command "users/home/masayuki.rbenv/shims/ruby" "Name of command to use for executing ruby code.")
p require "rubygems" p gem "test-unit" p RUBY_VERSION 'end'
デフォルトだとアルファベット順にテストが実行される.
which ruby gem install test-unit ruby test_sample.rb echo 'end'
/usr/bin/ruby Run options: # Running tests: :setup "test_bar" :treadown .:setup "test_foo" :treadown E Finished tests in 0.003415s, 585.6515 tests/s, 292.8258 assertions/s. 1) Error: test_foo(TestSample): NoMethodError: undefined method `assert_true' for #<TestSample:0x007fb08a8164c8> test_sample.rb:36:in `test_foo' /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/minitest/unit.rb:1301:in `run' /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/test/unit/testcase.rb:17:in `run' /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/minitest/unit.rb:919:in `block in _run_suite' /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/minitest/unit.rb:912:in `map' /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/minitest/unit.rb:912:in `_run_suite' /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/test/unit.rb:657:in `block in _run_suites' /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/test/unit.rb:655:in `each' /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/test/unit.rb:655:in `_run_suites' /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/minitest/unit.rb:867:in `_run_anything' /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/minitest/unit.rb:1060:in `run_tests' /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/minitest/unit.rb:1047:in `block in _run' /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/minitest/unit.rb:1046:in `each' /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/minitest/unit.rb:1046:in `_run' /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/minitest/unit.rb:1035:in `run' /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/test/unit.rb:21:in `run' /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/test/unit.rb:774:in `run' /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/test/unit.rb:366:in `block (2 levels) in autorun' /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/test/unit.rb:27:in `run_once' /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/test/unit.rb:365:in `block in autorun' 2 tests, 1 assertions, 0 failures, 1 errors, 0 skips ruby -v: ruby 2.0.0p481 (2014-05-08 revision 45883) [universal.x86_64-darwin14] end
アサーション
https://test-unit.github.io/test-unit/ja/Test/Unit/Assertions.html
のページの"Instance Method Summary"にあるassertで始まるメソッド群 が該当.各メソッドに飛べば実際のコード例が出てくるので,参照しつつ 適宜使い分ける.
便利な機能
RSpecだとdescribeとかでネスト出来るが,それをTest::Unitで出来る.実際 はTest::Unitでも継承すれば出来るけど,こっちの方が簡潔で好き.
class TestSample < Test::Unit::TestCase sub_test_case "Foo context" do
end
sub_test_case "Bar context" do
end end
メソッド名ベースだと使えない文字とかもあり,少し表現がしにくかっ た.けど,testを使えば解決!
class TestSample < Test::Unit::TestCase test "We can write good information" do # assert_nil(nil) end end
Test::Unitのgemにはdescriptionという機能があって,それとメソッド 定義のシンタックスシュガーらしい.以下のコードは上とほぼ同じ.
class TestSample < Test::Unit::TestCase description "We can write good information" def test_foo_bar
end end
sub_test_caseを使っていると,RSpecのbeforeのように各ケース毎に追 加でセットアップ処理を書きたくなる.TestCaseにはsetupメソッドがあ るけど,これはオーバーライドしてしまうので使えない.このような場 合にはsetupブロックを使う.setupメソッドとは違い,beforeのように 何個でも書ける.
class TestSample < Test::Unit::TestCase setup do puts "parent" end
sub_test_case "Sub!" do setup do puts "sub1" end
setup do puts "sub2" end
def test_sub assert_true(true) end end end
上の例を走らせると以下のようになる.もちろん,teardownも同様に出来る.
Loaded suite test_nest Started parent sub1 sub2 .
Finished in 0.000896 seconds.
注意点として,setupメソッドとsetupブロックでは優先順位が決まっている.気になるなら,setupブロックで統一した方が良いかもしれない.
テストの実行順序を指定出来る.どうしても定義順に実行したいのであれば,:definedを指定すれば上から順に実行される.
class TestSample < Test::Unit::TestCase self.test_order = :defined end
テストとデータを分けて書ける機能です.成功するテストや失敗するテ ストをまとめたりするのに便利.テストの中でeach回すのはイケてない し,かといってコピペで重複したテスト書くのもつらい.この機能使え ば,ちゃんとデータセット毎にテストがわかれます.
class TestSample < Test::Unit::TestCase # 'test1'がラベルで,[1, 1]がtest_equalの引数に渡される data( 'test1' => [1, 1], 'test2' => [2, 2]) def test_equal(data) expected, actual = data assert_equal(expected, actual) end data( 'test1' => [1, 2], 'test2' => [2, 3]) def test_not_equal(data) expected, actual = data assert_not_equal(expected, actual) end end
その他
Test::Unit::Assertions以下に定義して,そのファイルをrequireで読み 込むだけ.assert_blockとかbuild_messageとかのヘルパーが利用可能. assert_blockの中に条件を書く.
require 'test/unit/assertions' module Test::Unit::Assertions def assert_oreore(expected, actual) assert_block("failure message") do expected == (actual + 'oreore') end end end
コピペで使い回す
desc 'Run test_unit based test' Rake::TestTask.new do |t| # To run test for only one file (or file path pattern) # $ bundle exec rake test TEST=test/test_specified_path.rb t.libs << "test" t.test_files = Dir["test/**/test_*.rb"] t.verbose = true end
まとめ
RSpecほど機能がリッチじゃないので,足りないなら自分で書く必要があ るけど,Fluentdレベルだとそんなに困ってない. 個人的には, Parameterized Testが入ってくれれば嬉しいという所かな.
1.9 プログラミングの課題
sqlite3-ruby
1.10 sqlite3-ruby
関連サイト
gem
gem install sqlite3
sqlite
SQLite (wikipedia) 手軽なローカル・ファイル型の軽量データベース
setup
rm -f database.db
ruby
# coding: utf-8 require 'rubygems' require 'sqlite3' db = SQLite3::Database.new("database.db") sql = <<EOT create table Person ( name varchar(10), age integer, post varchar(200) ); EOT db.execute(sql) puts "New file is created." db.transaction do sql = "insert into Person values (?, ?, ?)" db.execute(sql, 'hoge', 26, 'hage') db.execute(sql, 'hage', 62, 'hoge') end db.execute('select * from Person') do |row| puts row.join("\t") end db.close 'end'
firefox sqlite database handling
firefox が使っている sqlite データベースをコピーして, テーブルのレコードを出力する。
ls ~/.mozilla/firefox cp -p ~/.mozilla/firefox/5rot7npz.default/places.sqlite .
# coding: utf-8 require 'rubygems' require 'sqlite3' require 'pp' file = "places.sqlite" db = SQLite3::Database.open(file) tables = db.execute("select tbl_name FROM sqlite_master WHERE type == 'table'") tables.flatten.each do |tbl| puts "== ", tbl db.results_as_hash = true db.execute("select * from #{tbl}") do |row| # puts row.join("\t") pp row end end p tables db.close 'end'
firefox sqlite database handling 2
ls -l ~/.mozilla/firefox/*/*sqlite
- *.sqlite3 をみんな出力してみましょう。
- lock されて開けないのもあるので,エラー処理をしましょう。
- 出力には,=pp= を使いましょう。
- 各dbの master record を読んでみましょう。
require 'rubygems' require 'sqlite3' require 'pp' # dir = '/users/home/masayuki/.mozilla/firefox/1dtrhim2.default-1450953083451/' dir = '/home/staff/suzuki/.mozilla/firefox/5rot7npz.default/' Dir.chdir(dir) do Dir.glob("*.sqlite").each do |db| puts "** #{db}" begin db = SQLite3::Database.open(db) results = db.execute("select * from sqlite_master") pp results rescue => e puts e end end end
ruby babel/sqlite3-master.rb
# coding: utf-8 require 'rubygems' require 'sqlite3' file = "content-prefs.sqlite" db = SQLite3::Database.open(file) tables = db.execute("select tbl_name FROM sqlite_master WHERE type == 'table'") tables.flatten.each do |tbl| puts "== ", tbl db.execute("select * from #{tbl}") do |row| puts row.join("\t") end end p tables db.close 'end'
関連サイト
gem
gem install sqlite3
sqlite
SQLite (wikipedia) 手軽なローカル・ファイル型の軽量データベース
sinatra-org
1.11 org-doc web service
references
- ~suzuki/meta-ruby.git/org/lects/note/sinatra-org/readme.org (self) ((@github/@cis/@s))
OrgBabelで文芸的プログラミング · ops●tokyo
すみません,このリンク切れていました。
org-converge wallyqs/org-converge: Literate reproducible runs using Org mode and Ruby.
A framework to create documented reproducible runs using Org Mode, borrowing several ideas of what is possible to do with tools like chef-solo, rake, foreman and capistrano.
- Sinatra: README (Japanese)
what
./notes にある .org 文書を表示する Webサービスを作成する。
how
- rubygems の sinatra,org-convergeを用いる
- readme.org に全てを記述する
directory
. +-- readme.org | +-- org +-- run.org | +-- src +-- app.rb | +-- Gemfile | +-- config.ru | +-- notes
mkdir -p org-doc/ org-doc/org org-doc/src org-doc/notes cp ./ruby-note-sinatra-org.org org-doc/readme.org
sinatraのための設定
bundler
bundler を gem install
which gem gem install bundler echo $PATH
/users/home/masayuki/.rbenv/Darwin.x86_64.14.5.0/shims/gem Bundler and RubyGems.org are free for anyone to use, but maintaining them costs more than $25,000 USD every month. Help us cover those costs so that we can keep the gem ecosystem free for everyone: https://ruby.to/support-bundler Successfully installed bundler-1.14.1 Parsing documentation for bundler-1.14.1 Installing ri documentation for bundler-1.14.1 Done installing documentation for bundler after 15 seconds 1 gem installed /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/users/home/masayuki/.rbenv/Darwin.x86_64.14.5.0/bin:/users/home/masayuki/.rbenv/Darwin.x86_64.14.5.0/shims:/users/home/masayuki/local/bin:/users/home/masayuki/.cask/bin:/users/home/masayuki/.rbenv/Darwin.x86_64.14.5.0/versions/bin:/users/home/masayuki/COMM/bin:/users/home/masayuki/bin:/opt/local/bin
gemfile
必要な gem を記述
# src/Gemfile gem 'sinatra' gem 'org-converge'
config.ru
sinatraアプリケーションを起動するための設定
# src/config.ru require './app.rb' run Sinatra::Application
service
application
sinatra のDSLで,Webサービスを記述:
# src/app.rb require 'sinatra' get '/' do 'OK' end get '/org' do Dir.glob('../notes/*.org').join("\n") end get '/org/*.org' do |doc| `(cd ../notes; sh ~/bin/org2html #{doc}.org)` `cat ../notes/#{doc}.html` end
ここでは,org->HTML変換には,~suzuki/COMM/bin/org2html コマンドを利用しています。
代わりに,((% pandoc -t html -f org %))コマンドを使ってもいいですし, rubygem/org-ruby を使ってもいいかもしれません。
起動
この文書を,emacs org-mode で C-c C-v C-t して,書き出し, 下記コマンドでサーバを立ち上げる。
org-converge org/run.org
確認
ブラウザで,下記URLにアクセスする:
- 127.0.0.1:9292/,
- 127.0.0.1:9292/org,
- 127.0.0.1:9292/org/ORG文書
起動用 org 文書 (org/run.org)
#+title: running the application #+include "org/app.org" ** run it #+name: server #+BEGIN_SRC sh :dir src bundle install bundle exec rackup #+END_SRC ** access #+name: getit #+BEGIN_SRC sh :wait 1 curl 127.0.0.1:9292/ 2>/dev/null sleep 2 curl 127.0.0.1:9292/org 2>/dev/null sleep 2 curl 127.0.0.1:9292/org/ruby-note.org 2>/dev/null sleep 2 #+END_SRC
1.12 クラスライブラリの抜粋
Rubyリファレンス
原典
method名やkeywordからクラスを探せるようにこの org文書を作成しました。
BasicObject
https://ref.xaio.jp/ruby/classes/basic_object
*~BasicObject~*クラスは、Ruby 1.9で新しく用意されたクラスで、~Object~ クラスの親クラスです。通常は、~BasicObject~オブジェクトを直接使うこと はありません。
~BasicObject~は~Object~や~Kernel~のメソッドを持たないので、「メソッド がほぼゼロの白紙のクラスを作りたい」というときは、~BasicObject~を継承 したサブクラスで実現できます。
メソッド一覧
クラスメソッド
new
: インスタンスの作成。
インスタンスメソッド
!
: 否定。!=
: 別のものか調べる。==
: オブジェクトの内容が同じか調べる。__send__
: メソッドを呼び出す。equal?
: 同じオブジェクトか調べる。instance_eval
: インスタンスの元でコードを実行。instance_exec
: インスタンスの元でコードを実行。
特別な役割のメソッド
initialize
: オブジェクトを作成(~new~)するとき呼ばれる。initialize_copy
: オブジェクトをコピー(~clone~、~dup~)するとき呼ばれる。method_missing
: メソッドが見つからないとき呼ばれる。singleton_method_added
: 特異メソッドを定義するとき呼ばれる。singleton_method_removed
: 特異メソッドを削除するとき呼ばれる。singleton_method_undefined
: 特異メソッドを未定義にするとき呼ばれる。
Sponsored by Oiax Inc. / Powered by Ruby on Rails and AmiWiki
Object
*~Object~*クラスは、すべてのクラスの親クラスです。
親クラスとモジュール
~Object~クラスは~Kernel~モジュールをインクルードしています。
~BasicObject~クラスが~Object~クラスの親クラスになりました。
Object < Kernel (< BasicObject)
メソッド一覧
クラスメソッド
new
: インスタンスの作成。
インスタンスメソッド
これらのメソッドは、実際には~Kernel~モジュールの~public~なメソッドとして実装されていますが、一般的に~Object~クラスのメソッドとして扱われます。また、この一覧には~BasicObject~のメソッドも混ぜてあります。
!
: 否定。Ruby 1.9!=
: 別のものか調べる。Ruby 1.9!~
: パターンマッチの否定。Ruby 1.9==
: オブジェクトの内容が同じか調べる。===
: ~case~式でオブジェクトをテストする。~=
: パターンマッチ。__id__
: オブジェクトIDを返す。__send__
: メソッドを呼び出す。class
: オブジェクトのクラスを返す。clone
: オブジェクトのコピーを作成する。define_singleton_method
: 特異メソッドを定義する。Ruby 1.9display
: オブジェクトを文字列として出力する。dup
: オブジェクトのコピーを作成する。eql?
: ハッシュのキーとして同じか調べる。equal?
: 同じオブジェクトか調べる。enum_for
: ~Enumerator~オブジェクトの作成。Ruby 1.8.7extend
: モジュールのメソッドを取り込む。freeze
: オブジェクトを凍結する。frozen?
: オブジェクトの凍結状態を調べる。hash
: ハッシュ値を返す。id
: オブジェクトIDを返す。+Ruby 1.9+inspect
: 読みやすい文字列に変換。instance_eval
: インスタンスの元でコードを実行。instance_exec
: インスタンスの元でコードを実行。Ruby 1.8.7instance_of?
: クラスに属しているか調べる。instance_variable_defined?
: インスタンス変数があるか調べる。instance_variable_get
: インスタンス変数の値を得る。instance_variable_set
: インスタンス変数の値を変える。instance_variables
: インスタンス変数の名前を配列で返す。is_a?
: クラスに属しているか調べる。kind_of?
: クラスに属しているか調べる。method
: メソッドから~Method~オブジェクトを作成。methods
: メソッドの名前を配列で返す。nil?
: ~nil~かどうか調べる。object_id
: オブジェクトIDを返す。private_methods
: ~private~なメソッドの名前を配列で返す。protected_methods
: ~protected~なメソッドの名前を配列で返す。public_method
: ~public~なメソッドから~Method~オブジェクトを作成。Ruby 1.9public_methods
: ~public~なメソッドの名前を配列で返す。public_send
: ~public~なメソッドを呼び出す。Ruby 1.9respond_to?
: メソッドを呼び出せるか調べる。send
: メソッドを呼び出す。singleton_class
: 特異クラスを返す。Ruby 1.9.2singleton_methods
: 特異メソッドの名前を配列で返す。taint
: オブジェクトを汚染する。tainted?
: 汚染状態を調べる。tap
: ブロックに自身を渡し、自身を返す。Ruby 1.8.7to_a
: 配列に変換。+Ruby 1.9+to_enum
: ~Enumerator~オブジェクトの作成。Ruby 1.8.7to_s
: 文字列に変換。trust
: 信頼される状態に戻す。Ruby 1.9type
: オブジェクトのクラスを返す。+Ruby 1.9+untaint
: オブジェクトの汚染を除く。untrust
: オブジェクトを信頼されない状態にする。Ruby 1.9untrusted?
: 信頼状態を調べる。Ruby 1.9
privateメソッド
remove_instance_variable
: インスタンス変数の削除。
Rubyから呼び出されるメソッド
initialize
: オブジェクトを作成(~new~)するとき呼ばれる。initialize_copy
: オブジェクトをコピー(~clone~、~dup~)するとき呼ばれる。method_missing
: メソッドが見つからないとき呼ばれる。respond_to_missing?
: ~respond_to?~が~false~のとき呼ばれる。Ruby 1.9.2singleton_method_added
: 特異メソッドを定義するとき呼ばれる。singleton_method_removed
: 特異メソッドを削除するとき呼ばれる。singleton_method_undefined
: 特異メソッドを未定義にするとき呼ばれる。
Module
~Module~クラスは、クラスとモジュールを表すクラスです。~Class~クラスは ~Module~のサブクラスで、クラスだけを表します。
クラス・モジュールを定義すると、クラス名・モジュール名は ~Class~/~Module~オブジェクトを指す変数(定数)になります。 ~Class~/~Module~オブジェクトをレシーバにすれば、~Class~/~Module~クラス の~public~メソッドを呼び出せます。
クラス・モジュール定義の中のように、~self~が~Class~/~Module~オブジェク トである場所では、~Class~/~Module~クラスの~private~メソッドを呼び出せ ます。~attr_accessor~や~include~は~Module~クラスの~private~メソッドで す。
親クラスとモジュール
~Module~クラスの親クラスは~Object~クラスです。
Module < Object < Kernel (< BasicObject)
メソッド一覧
クラスメソッド
constants
: 現在使える定数名の一覧を返す。nesting
: 現在のクラス・モジュールのネスト状態を調べる。new
: モジュール定義を使わずにモジュールを作成。
publicなインスタンスメソッド
<
,<=
,>
,>=
: 2つのクラスやモジュールの関係を調べる。<=>
: 2つのクラスやモジュールの関係を調べる。==
: 同じものか調べる。===
: クラスに属しているか調べる。ancestors
: 祖先クラスとモジュールの一覧を返す。autoload
: 定数に対応するファイルを自動ロードする。autoload?
: 定数が自動ロードされるか調べる。class_eval
: クラスやモジュールの元でコードを実行。class_exec
: クラスやモジュールの元でコードを実行。Ruby 1.8.7class_variable_defined?
: クラス変数があるか調べる。class_variables
: クラス変数名の一覧を返す。const_defined?
: 定数があるか調べる。const_get
: 定数の値を得る。const_set
: 定数を設定する。constants
: 定数名の一覧を返す。freeze
: クラスやモジュールを凍結する。include?
: モジュールをインクルードしているか調べる。included_modules
: インクルードしているモジュールの一覧を返す。instance_method
: メソッドから~UnboundMethod~オブジェクトを作成。instance_methods
: メソッドの名前を配列で返す。method_defined?
: メソッドがあるか調べる。module_eval
: クラスやモジュールの元でコードを実行。module_exec
: クラスやモジュールの元でコードを実行。Ruby 1.8.7name
: クラスやモジュールの名前を返す。private_class_method
: クラスメソッドを~private~にする。private_instance_methods
: ~private~メソッドの名前を配列で返す。private_method_defined?
: ~private~メソッドがあるか調べる。protected_instance_methods
: ~protected~メソッドの名前を配列で返す。protected_method_defined?
: ~protected~メソッドがあるか調べる。public_class_method
: クラスメソッドを~public~にする。public_instance_method
: ~public~メソッドから~UnboundMethod~オブジェクトを作成。Ruby 1.9public_instance_methods
: ~public~メソッドの名前を配列で返す。public_method_defined?
: ~public~メソッドがあるか調べる。to_s
: クラスやモジュールを表す文字列を返す。
以下のメソッドは、Ruby 1.8では~private~でしたが、Ruby 1.9では~public~になりました。
class_variable_get
: クラス変数の値を得る。class_variable_set
: クラス変数を設定する。remove_class_variable
: クラス変数の削除。
privateなインスタンスメソッド
alias_method
: メソッドに別名を付ける。attr
: インスタンス変数のアクセサを定義する。attr_accessor
: インスタンス変数のアクセサを定義する。attr_reader
: インスタンス変数の読み出し専用アクセサを定義する。attr_writer
: インスタンス変数の書き込み専用アクセサを定義する。define_method
: メソッドを定義する。include
: モジュールをインクルードする。module_function
: モジュールのメソッドをモジュール関数にする。private
: メソッドを~private~にする。protected
: メソッドを~protected~にする。public
: メソッドを~public~にする。remove_const
: 定数の削除。remove_method
: メソッドの削除。undef_method
: メソッドを未定義にする。
Rubyから呼び出されるメソッド
append_features
: インクルードされる前に呼ばれる。const_missing
: 存在しない定数を参照したときに呼ばれる。included
: インクルードされたあとで呼ばれる。extended
: オブジェクトに取り込まれたあとで呼ばれる。extend_object
: オブジェクトに取り込まれる前に呼ばれる。method_added
: メソッドを定義したときに呼ばれる。method_removed
: メソッドを削除したときに呼ばれる。method_undefined
: メソッドを未定義にしたときに呼ばれる。
Class
~Class~クラスは、クラスを表すクラスで、~Module~クラスのサブクラスです。
クラスに関する機能のほとんどは、~Module~クラスに実装されていますので、~Module~クラスのほうを先に調べるといいでしょう。~Class~クラスの機能は、「~Module~の機能+インスタンスの作成とクラスの継承」です。
親クラスとモジュール
~Class~クラスの親クラスは~Module~クラスです。
Class < Module < Object < Kernel (< BasicObject)
メソッド一覧
クラスメソッド
new
: クラス定義を使わずにクラスを作成。Class.new で無名クラスを作る
インスタンスメソッド
allocate
: インスタンスの作成。new
: インスタンスの作成と初期化。superclass
: 親クラスを返す。
2 memo
2.1 memo
Doing test-unit
Doing poker.org
~suzuki/COMM/Lects/meta-ruby/site/lects/poker の下に org 文書を作り ました。
global
ソースコードを快適に読むための GNU GLOBAL 入門 (前編) - まちゅダイアリー(2009-03-07) globalを使いブラウザで快適にソースコードを読む - ほろあま記念館
- ~suzuki/public_html/Documents/ruby20に置きました。が,cgi動かず。
- global-6.5.1 install しました。
- ~suzuki/local/bin/gtags
- ruby-2.0.0-p353 download し,gtags, htags しておきました。
- ~suzuki/working/ruby20/ruby-2.0.0-p353
ruby-2.0.0-p353 ソースコードをHTML化したもの
ソースコード解説
ソースコード pry-doc
EmacsでPATHの設定が引き継がれない問題をエレガントに解決する - Qiita
gem install spreadsheet for meta-ruby
meta-ruby 講義内容
- meta な説明
- meta programming
- class library を使った ruby プログラミング
- OO
Done .ob org-mode #+babel_include の導入 include babel org
why
include ファイル中の named_src_block の noweb 参照ができない
how
- 同一ファイル中の named_src_block は noweb 参照ができるので, include を展開することにした。
- 通常の include は展開したくないので, babel_include だけ展開する ことにした。
script
#!/usr/bin/env ruby # coding: utf-8 def org_babel_expand_include (file) File.open(file, 'r:utf-8') do |io| io.read.each_line do |line| if line =~ /^#\+babel_include:\s*(\S+)/ org_babel_expand_include($1) else print line end end end end if __FILE__ == $0 org_babel_expand_include(ARGV[0]) end
working directory
Doing org-tangle auto tangle babel org
tangle を make できるように
ruby gem org-converge 中の org-tangle
:nowebの機能が使えないので,あきらめる
シェルコマンド化
org2html と同様に, org_tangle を作成
Makefile 中の tab が展開されるので, config/emacs-org.el を読むよ うにする
#!/usr/bin/env bash # https://blog.nguyenvq.com/2010/10/30/bash-batch-script-to-convert-org-mode-file-to-html/ # orgdir=/r/src/org-mode/lisp/ # Git版org-modeのディレクトリ # opts="-l ~/.org2html-batch.el" # カスタマイズしなければ "" にする opts="-l ~/.emacs.d/config/emacs-org.el" f="" for file in "$@" do # f="${f} --visit ${file} --funcall org-export-as-html-batch" # f="${f} --visit ${file} --funcall org-html-export-as-html" f="${f} --visit ${file} --funcall org-babel-tangle" done # Emacs標準添付のorg-modeを使う場合はこっち ~/bin/emacs --batch -l org $opts $f #~/bin/emacs --batch -q --no-site-file -l org $opts $f # Git版org-modeを使う場合はこっち # emacs --batch -q --no-site-file -L $orgdir -l org $opts $f
new org-mode babel-include を展開する
file:///users/home/masayuki/COMM/Prog/org/babel-include/
~/COMM/bin/babel-expand.rb
ruby 日本語
ruby -K [e|s|u|n] euc-jp|cp932|utf-8|ascii-8
internal_encoding, external_encoding default_ … magic comment
# coding:utf-8
ruby入門のサイトを変更したい
org babelを調べる
meta-ruby
クラス・モジュールの概念 Ruby - Qiita https://qiita.com/ToruFukui/items/2dd4d2d1ce6ed05928de
カレントオブジェクトselfについて Ruby - Qiita https://qiita.com/ToruFukui/items/be29968da6dc9d125315
誤解されている 6 つの Ruby の機能の真相を知る https://www.ibm.com/developerworks/jp/opensource/library/os-sixrubyfeatures/
Rubyを勉強する上で有用な情報源まとめてみた - Qiita
ob-ruby
:session name を指定すると*nameバッファで inf-ruby が動く 実行はしているが,プロンプトの定義がおかしいためか,結果が取れてい ない。
pry をやめるとうまく動く
若手エンジニア/初心者のためのRuby 2.1入門(12):難しいが強力! Rubyのメタプログラミング、self、特異クラス/メソッド、オープンクラスとモンキーパッチ (1/4) - @IT
Ruby - 【mkdirからデプロイまで3分】Sinatra+Haml+Sass+Coffee でサクッとHerokuに公開して捨てるwebアプリ - Qiita
emacs-24.5 for @cis.iwate-u.ac.jp
~/bin/org2html index.org
Cannot fontify src block (htmlize.el >= 1.34 required)
- melpa の htmlize の version は,1.47 なのに
Todo ditaa@github install後,ditaa.jar が見つからない
log new_file graphviz
Emacs org-modeを使ってみる: (19) graphvizとditaaの図を埋め込む - 屯遁のパズルとプログラミングの日記
https://d.hatena.ne.jp/tamura70/20100222/org
org-modeでGraphviz(dot)を使う https://misohena.jp/article/emacs_org_textfigures/dot.html
memo lstree directory
org2HTMLの自動化
~/COMM/bin/org2html