カテゴリー「プログラミング」の104件の記事

rubyのLOAD_PATH($:)

人様の書いたrubyソースコードを読もうとしたら、のっけから読めない行がありました。

$:.unshift('/home/bin/ruby')

「$:.」ってなんだ?何この変数?とドツボにはまってしまいました。そんな訳ないですね。「$:」という変数に対してunshiftを実行しているだけですね。

「$:」でも見たことなかったので調べてみると、「$LOAD_PATH」の別名らしいです。で、配列の中身を見てみると。

p $:
--------------------------------------------
["/usr/local/lib/ruby/site_ruby/1.8",
"/usr/local/lib/ruby/site_ruby/1.8/i686-linux",
"/usr/local/lib/ruby/site_ruby",
"/usr/local/lib/ruby/vendor_ruby/1.8",
"/usr/local/lib/ruby/vendor_ruby/1.8/i686-linux",
"/usr/local/lib/ruby/vendor_ruby",
"/usr/local/lib/ruby/1.8",
"/usr/local/lib/ruby/1.8/i686-linux",
"."]

--------------------------------------------

なるほど、rubyライブラリへのパス一覧が入った配列ですね。で、上記の処理を実行後に再度配列の中身を見てみます。

$:.unshift('/home/bin/ruby')
p $:

--------------------------------------------
["/home/bin/abe/ruby",
"/usr/local/lib/ruby/site_ruby/1.8",
"/usr/local/lib/ruby/site_ruby/1.8/i686-linux",
"/usr/local/lib/ruby/site_ruby",
"/usr/local/lib/ruby/vendor_ruby/1.8",
"/usr/local/lib/ruby/vendor_ruby/1.8/i686-linux",
"/usr/local/lib/ruby/vendor_ruby",
"/usr/local/lib/ruby/1.8",
"/usr/local/lib/ruby/1.8/i686-linux",
"."]

--------------------------------------------

ということで、デフォルトのライブラリへのパス一覧配列に、自作のライブラリへのパスも追加して便利に使ってるということでした。

Rubyでは++演算子によるインクリメントができない

Rubyでは++演算子によるインクリメントができない

プログラム内のループ処理などで便利なインクリメント演算子++ですが、こちらRubyでは使用できないようです。++はPerlやPHPでプログラミングする際にはよく使いますが、Ruby以外にも使用できない言語はあるのかも知れません。

Perl
--------------------------
#!/usr/local/bin/perl

$data = 1;
$data++;

print $data

>2
--------------------------

上記のような処理をRubyで行いたい場合、以下のように記述します。

Ruby
--------------------------
#!/usr/local/bin/ruby

data = 1
data +=1

print data

>2
--------------------------

Rubyが++演算子を許可していない理由

気になったので、なんで使えないのか調べて見ました。Rubyではその他の多くのプログラミング言語と違い、「変数」を「オブジェクト」として扱っていないようです。

そのためRubyにおいての変数は、数そのものへのポインタということになり、ここに破壊的動作である++演算子を使用してしまうと、「ポインタの位置がインクリメントされる」という正しく破壊的な結果がもたらされてしまうようです。

その結果どういうことになるかというと、変数の値だけでなく、プログラム内で扱っている1という数字へのポインタが2を向くようになってしまいます。つまり、そのプログラム内では「1も2も2」に変更されてしまうのです。

そのため、Ruby開発者のまつもと氏は「本当は使えるようにしたいけど、Rubyの設計上禁止せざるを得ない」というようなことを言っています。

参考:http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/5323

このためRubyではインクリメントの++演算子と同様に、デクリメントのーー演算子も使用を禁止しています。

++演算子を使用できない理屈は分かってスッキリしたのですが、今度は使用を禁止せざるを得ない、Rubyそのものの設計が気になってきました。。こちらの調査はとても大変そうなので、また今度にします。

ハッシュ関数

ハッシュ関数は、与えられたデータを一定のデータの要約を出力する処理のこと。ハッシュ関数によって得られた値をハッシュ値といいます。

ハッシュ関数の特徴として、「似たデータのハッシュ値は似ていない」「生成されるハッシュ値に偏りがない」などがあります。

■例
5桁の整数a1a2a3a4a5のハッシュ値を求める。ここでa1a2a3a4a5は54321とする。ハッシュ関数はmod(a1+a2+a3+a4+a5, 13)とする。mod(x, 13)の値は、xを13で割った余りとする。

mod(a1+a2+a3+a4+a5, 13) = mod(5+4+3+2+1, 13) = mod(15, 13) = 2

ファイルディスクリプタ

プログラムがアクセスするファイルや標準入出力などをOSが識別するために用いる識別子。0から順番に整数の値が割り当てられる。OSによってはファイルディスクリプタにバッファ管理機能なども含めた「ファイルハンドル」と呼ばれる管理体系が存在する。

ファイルディスクリプタには、識別子とともにファイル名、ファイルサイズ、プログラムが操作中のファイル内の位置、ファイル作成、更新日時などの情報が含まれており、OSは識別子によってどのファイルを操作するかを判断する。

通常、0:標準入力(stdin)、1:標準出力(stdout)、2:標準エラー出力(stderr)の3つはOS(シェル)が最初に用意するため、プログラムがファイルをオープンすると「3」から順番にディスクリプタが割り当てられる。

ラッパー

包装紙、カバー、覆うもの、包むもの、などの意味を持つ英単語。

プログラミングの分野で、あるクラスや関数、データ型などが提供する機能やデータを含み、別の形で提供するもののことをラッパーという。元の機能を包み、覆い隠す役割を果たすためにこのように呼ばれる。

ラッパーが必要な状況は様々で、元のクラスなどがそのままでは利用できない別の環境で利用できるようにしたり、煩雑な仕様などを隠蔽してシンプルに操作できるようにしたり、別の機能を追加したりするのに使われる。

メモリリーク

コンピュータの動作中に、使用可能なメモリ容量がだんだん減っていく現象。OSやアプリケーションソフトが処理のために占有したメモリ領域を、なんらかの理由で開放しないまま放置してしまうために起きる。

多くの場合OSのメモリ管理方法に問題があったり、アプリケーションソフトんいバグが残っていたりすることが原因である。メモリリークにより利用可能なメモリ領域が減少すると、システムの性能が低下したり、不安定になったりする。これを解消するにはシステムを再起動する必要がある。

Rubyの定数について

■例
FOO_BAR

アルファベット大文字[A - Z]で始まる識別子は定数となる。定数の定義と初期化は代入によって行われる。メソッドの中では定義できない。一度定義された定数に再び代入を行おうとすると警告メッセージが出る。定義されていない定数にアクセスすると例外NameErrotが発生します。

単語の区切りはアンダーバー(_)を使用します。

Rubyソース上に漢字を使用する場合の注意点

ruby1.6以降、デフォルトでは漢字コードを解釈しなくなりました。漢字を扱いたい場合は$KCODEを設定する必要があります。

$KCODEはRubyの組込みのグローバル変数で、初期値は"NONE"が入っています。ここにマルチバイト文字列エンコーディングを指定することができます。以下のように、インタプリタにオプションとして指定します。

■EUC
#! ruby -Ke

■SJIS
#! ruby -Ks

■UTF-8
#! ruby -Ku

これでエンコーディングの指定がスクリプトに埋め込まれたことになります。

コンストラクタ

コンストラクタは、オブジェクト指向のプログラミング言語で新たなオブジェクトを生成する際に呼び出されて内容の初期化などを行う関数、メソッドの事。Java、C++、PHP、Rubyなどに見られる。

オブジェクトの生成は、

1.メモリ割当(allocation)

2.初期化(initialization)

の二段階を経て行われるが、コンストラクタを持つ言語ではアロケーションは言語機能に組み込まれ、初期化用のコードのみを記述するのが普通である。

Java、C++ではコンストラクタを「クラス名と同一の名前を持つ関数(メソッド)」と定義している。

Rubyではそのままinitializeメソッドを使用する。

undefined local variable or method `ls' for # (NameError)

undefined local variable or method `ls' for #<Object:0x40286c90> (NameError)

上記のエラー文はrubyでeval関数でlinuxコマンドのlsを指定したときに出ました。

意味は「そのようなローカル変数もメソッドも定義されていませんよ。NameErrorです。」とのこと。変数のことをvariableを呼ぶことを知らなかったので、念のためのメモ。

より以前の記事一覧