Hatena::ブログ(Diary)

西尾泰和のはてなダイアリー

2012-01-27

他の言語に慣れた人がRubyを使ったときにつまずきがちな9つのポイント

他の言語に慣れた人がPythonを使ったときにつまずきがちな9つのポイントの続編。ささださんも書いています see: だいありー

0は真, 空文字列も真

C言語などと違って、0は偽ではない。PythonJavaScript, PHPと違って空文字列も偽ではない。

>if 0 then print "true!\n" end
true!

> if "" then print "true!\n" end
(irb):1: warning: string literal in condition
true!

括弧がなくても0引数での関数呼び出しが起きる

PythonやJavaScriptでは式中に現れた関数名は関数を指す。しかしRubyでは0引数での呼び出しが行われる。

# Python
>>> def foo(): print "foo!"
... 
>>> foo
<function foo at 0x100445f50>
# Ruby
> def foo() print "foo!\n" end
=> nil
> foo # メソッド呼び出しが起きる
foo!
=> nil

変数はすべて参照

> a = []
> b = a
> b << 1
> a
=> [1]

ソースコードのエンコーディング

Ruby1.9ではソースコードのエンコーディングを指定せずにソースコード中でASCII以外の文字を使うとシンタックスエラーになる。

$ cat > t.rb
p "ほげ"
$ ruby1.9 t.rb 
t.rb:1: invalid multibyte char (US-ASCII)
t.rb:1: invalid multibyte char (US-ASCII)

PythonやScheme同様の方法でソースコードのエンコーディングを指定できる。詳しいことはこちら:多言語化

# -*- coding: utf-8 -*-
p "ほげ"

1.8で下記のようなコードをSJISで書くと構文エラー(unterminated string meets end of file)になる。ruby起動時のオプションに-Ksを指定する必要がある。

print "機能"

JIS規格に準拠した処理系が、ソースコードにUS-ASCII以外の文字が入っていた場合にどういう挙動をするかは未規定である。

整数がオーバーフローしない

整数の加減乗除やシフト演算で整数(Fixnum)の範囲を超えた場合、Cなどのようにあふれたビットを捨てて範囲内に収めるのではなく、上限のないBignumに変換される。そして文字列表示を見ても区別がつきにくい。

> x = -4611686018427387904
> x.class
=> Fixnum
> x /= -1
=> 4611686018427387904
> x.class
=> Bignum

Cで書かれたアルゴリズムを逐語訳したりすると、かなり気づきにくいバグが入ってしまう。

同名のクラス定義があった場合、衝突せずに合成される

class Foo
  def x; 1 end
end

class Foo
  def y; 2 end
end

p Foo.new.x #=> 1 と表示される
p Foo.new.y #=> 2 と表示される

場合によっては便利に使えるケースもあるかも知れない。ソースコードを読む人が意図的に合成されていることを知らないと混乱しそうではある。

あと3つは募集中です

rahaemarahaema 2012/01/27 19:15 変数のスコープに最初戸惑うというのはどうですか?以下がエラーになります。
hi = "Hi"
def sayHi
puts hi
end
sayHi

o_showo_show 2012/01/27 19:48 >いま標準化が進められているのは1.8ベースなんだっけ?
JIS X 3017(RubyのJIS規格)は、1.8と1.9の共通部分だけ規定されています。
またプログラムはASCIIのみで構成されることが前提とのことです。
ISOに提案している方についてはわかりません。

Ruby1.8系は2013年6月まででセキュリティフィックスの提供も終了するので、
標準化はともかくこれから始める人はあまり考えなくていいと思います。

o_showo_show 2012/01/28 03:28 すみません。JIS X 3017のエンコーディングについて触れてる箇所を持って来ました。

>プログラムは,プログラムテキストで表現
>される。プログラムテキストは,《ソース
>文字》の並びである。《ソース文字》
>は,ISO/IEC 646:1991 の国際基準版
>(IRV:International Reference
>Version)にある文字である。その他の文字
>集合及びエンコーディングをサポートする
>かどうかは,未規定とする。

「ISO/IEC 646」というのはASCIIのことです。
そして「禁止」ではなく「未規定」です、ってことでした。
どちらにしろ、実際にRubyを書く時はもちろんソースコードにマルチバイトを含めて構いません。

nishiohirokazunishiohirokazu 2012/01/28 09:04 情報ありがとうございます。修正しておきます。

alhalh 2012/01/28 12:03 >> 変数はすべて参照
これは嘘ではないですか.
配列がオブジェクトですから参照型のセマンティクスをしているだけで,
変数が参照だから同時に書き変わっているわけではないです.

toyoshitoyoshi 2012/02/01 09:00 メソッドの返り値が最後に評価した値ってのはどうでしょう

投稿したコメントは管理者が承認するまで公開されません。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

Connection: close