メタプログラミングRuby第二章(2.2~)
クラスの真相
Classクラスのインスタンスはクラス!
クラスのメソッドはClassクラスのインスタンスメソッド
Classクラスとは?
クラス(ここでいうクラス名は大文字) はClassクラスのインスタンスである。
Stringクラスを例にとると String.class #Class ←Classクラス
moduleとは?
全てのクラスはモジュールである。 Classはインスタンスメソッド(new、allocate、superclass)を追加したモジュールである。 モジュールの使い分けとしては共通的なものはまとめてることが多い。 そしてクラスからmix-inして使えば良い。
定数とは?
定数とは大文字で始まるもの クラス名は定数
定数と変数の違いはスコープ範囲が違う
定数はディレクトリが違えば、一緒ではない、 定数の参照はclass外(含Module)では コロン2つをつけて指定する。 クラス外で定数を定義した場合、暗黙的に Objectクラス の定数になる
module M class C A = "クラス内" p A end A = "モジュール内" p C::A #定数 p A #AA end B = "モジュール外" p M::C::A #クラス内 p M::A #モジュール内 p Object::B #モジュール外 p B #モジュール外 p B.class #String p B.class.superclass #Object
定数が違うと便利なこと
クラス名が衝突してもモジュールで囲えば名前衝突を回避出来る
メタプログラミングRuby二章(2.2途中まで)
第二章(途中まで)書きます。
オープンクラスとは?
既存のクラスを再定義することです。
以下のコードを見て下さい。
これはStringクラスのメソッドを拡張した例です。
class String def dokkiri! return "!" end end p "test".class #String p "test".dokkiri! #!
補足 オブジェクトとClass
僕はこの文読んだ時よくわからなかったです。 なんで、基本的なクラスの話を噛み砕いて説明します 上のソース例の「"test"」は文字列オブジェクトを示しています。 オブジェクトは様々なものありますが、 代表的なものは数値(1や100)、文字列、配列などがあります。
そしてオブジェクトはクラスに属しています。 直感的に言えば性質みたいなものでしょうか。 性質(クラス)に応じて文字列だから「大文字に変換」といった 性質(クラス)に合わせた機能(メソッド)が使えます。 オブジェクトが属するクラスを探すにはclassメソッドを使います。
今回用いたオープンクラスはclass Stringに属するメソッドを追加しました。
しかし、注意があります。
以下のコードを見て下さい。
p "test".capitalize #Test class String def capitalize return self + "!" end end p "test".capitalize # "test!"
オープンクラスは既存のメソッド(capitalize)も変更出来るので 既存のプログラムの挙動が変わり、バグを引き起こすことがあります。 (モンキーパッチという) よって、取扱には十分注意です。
インスタンス変数とは?
インスタンス変数とはクラスをインスタンス化した際に用いる変数です。(先頭に@をつけます) インスタンス変数はクラスに属しているわけではなく、クラスのオブジェクトに紐付いています。
コード例を見てみます。
class Test def test @test = "test" end end obj = Test.new p obj.instance_variables #インスタン変数なし obj2 = Test.new obj.test #@testを定義 p obj.instance_variables #@test
メソッド(ここではtest2)はクラスに属しているため、 クラス(Test)をインスタンス化(オブジェクト化)しただけでは、 メソッド(test)は呼び出されない。 直感的にいうと、Testクラスのインスタンス化はあくまでもメソッド(インスタンスメソッド)の リンクを使えるようにしただけといったところでしょうか。
インスタンス化してすぐにインスタンス変数を使うには 下のコードのようにinitializeメソッドを使う必要があります。
class Test2 def initialize @test2 = "test2" end end obj3 = Test2.new p obj3.instance_variables #@test2
自分の理解が不確かなところもあります。 もし、この記事をみている方で「違うぞ」と思った方は コメントお願い致します。
メタプログラミング1章 準備
第一章は分量も多くないため、頭の整理のため オブジェクト志向についてまとめておきます。
クラス
教科書通りの説明ですと、クラスとは「設計図」です。 よくある例ですと、たい焼きの型ですね オブジェクト志向は再利用を目的としています。
例えば、「たい焼き」を構成するものは 「おおきさ」「素材」「あんこ」「価格」 といったものがあると思います。
ここでは「たい焼き」の情報(素材・中身・個数)を 表示するプログラムを作ります。
今回はクラスを用いて表現してみます。
素材は共通的に用いるため、 クラス変数 を用います。 クラス変数は頭に「@@」をつけます。 代入可能でクラス内での共通的な定数です。
実行方法はclass.newでオブジェクト化して、メソッドを使用します。 initializeはオブジェクトを作成する際に実行した際、自動で呼び出す処理です。intializeは引数を指定することが出来ます。
オブジェクト化した際のメソッド「order」は インスタンスメソッドと呼ばれます。 インスタンスメソッドはクラスから作成されたオブジェクトしか 呼び出すことは出来ません。
class Taiyaki # (素材・中身・個数) @@material = "komugi" #素材は決まっている。 def initialize(order=1,content="azuki") #初期設定 @order_num = order @order_content = content end def order #インスタンスメソッド puts "素材は#{@@material}です。個数は\n#{@order_num}\n中身は#{@order_content}" end end puts Taiyaki.new.order puts Taiyaki.new(2,"チーズ").order
メタプログラミングRubyを読む
はじめに
これからメタプログラミングRubyを読んでわかったことをまとめていきます。
編集方針(随時更新)
- 基礎的なこともまとめる。 オライリー特有の「わかっているだろ?」的記述を出来る限り自分の 中で噛み砕いて説明
wgetコマンド使い方
wgetとは
ウェブページからコンテンツをダウンロードする際に利用します。 よくある利用例としてはウェブサイトのページをダウンロードしたり、 画像を取得したりします。
使用方法
Macから使うにはwgetコマンドをインストールする必要があります。
$ brew install wget
して下さい!
ウェブページ保存方法
$ wget http://www.yahoo.co.jp #yahoo 取得
ファイル名を指定するには
-O オプションを使う
$ wget http://www.yahoo.co.jp -O yahoo.html #yahoo 取得
特定のファイルを保存するには
-i オプションを使う
$ wget -i *.gif http://www.yahoo.co.jp -i *.gif #yahoo 取得
簡単ですが、以上となります。
サーバーコマンド
サーバー利用
先日、サーバーを利用したので、その際に用いた コマンド及び、(これから使うであろう)コマンドを 備忘録として残しておきます。
Topコマンド
Topコマンドを用いると、システム全体の負荷・メモリ稼働状況が 把握出来るようです。 以下にコマンド例を記載します。
$top #CPU順にソート $top -a (shift + m) #メモリ順にソート
その他、有益と思われるコマンド
df #ディスクの空き容量を把握 free #メモリの空き容量
サーバーについては勉強中なので、継続して更新していきます。
新しいファイルを何個も作るには
UNIXコマンドでファイル作成
僕は新しいファイルを作る際、GUIを通じて行っていました。
普段使う際は問題ないのですが、大量のファイルが必要なときは問題になりますね。 例えば1〜99のjsonファイルを作る際にはいちいち、マウスを使って作るのは非効率ですね。 なんで、備忘録としてUNIXコマンドで出来るファイル作成方法をまとめておきます。
例① 1.json作成
$ touch 1.json
連番も出来るみたいです。
例② 1.txt、2.txt作成
$ touch {1..2}.txt
もっと複雑にしたい場合はrubyなどのプログラミング言語 を使ったほうが良さそうです。 その場合は ダブルクオートを使って制御すればOKです。
count = 0 10.times{ if count % 2 == 0 `touch #{count}.json ` else `touch #{count}.txt ` end count += 1 }