ウェブエンジニア珍道中

日々の技術的に関する経験を書いていきます。脱線もしますが助けになれば幸いです。

RubyのBooleanについて(一発ネタ)

今回はただの一発ネタです。

Rubyの真偽値のtruefalseには.!メソッドというものがあるのを知りました。

真偽値をひっくり返すものです。

true.! # false

もちろん、頭に!を付けてもOKです

!true.! # true

true!メソッドでfalseになって、頭の!でtrueに戻ってきます。

大体オチが見えたと思いますが、こんな書き方ができます。

true.!.!.!.!.!.!.!.! # true

!!!!!!!!!true.!.!.!.!.!.!.!.! # false

!!!(!!!(!!!!true)).!.!.!.!.!.!.!.! # true

滅茶苦茶ですが、動きますw

仕事で使うとぶっ飛ばされると思うので、小ネタとして紹介しました。

ではでは。

Rubyのtapメソッドが便利なので紹介する

RubyのObject#tapが便利だったので紹介します。(昔からあるらしいけど)

tapメソッドとは

ブロック文を渡すと中身の処理を走らせてレシーバを返すメソッドです。

hoge = "test".tap do |string|
  puts string
  true
end
puts hoge # "test"

Objectクラスに定義されているので大体のクラスで使えます。

メリット

レシーバを返さない破壊的メソッドにレシーバを返させることができます。

いちいち変数を作って入れて…って処理を省いたりできます。

Railsのsaveとか

例えば「DBに保存してActiveRecordのインスタンス変数からidを取り出して返すメソッド」なんてものを作る時には

def save_something_record
  some_model = SomeModel.new(params)
  some_model.save # saveの返り値はtrue/false
  some_model.id
end

saveメソッドがtrue/falseを返すために変数に一度入れないといけないところが

def save_something_record
  SomeModel.new(params).tap(&:save).id
end

と1行で書けます。saveメソッドはtrue/falseを返しますが、tapメソッドにより保存処理後のレシーバが返されます。

RSpecなんかでちょっとしたテストデータを用意する時もちょっとした小技として使えます。

HogeServiceを作って実行した後のインスタンスが欲しいなんて時には以下でOKです。

let(:executed_hoge_service) { HogeService.new.tap(&:execute) }

変数名とかを考える手間が減って便利な小技でした。

rubyでサンプルデータを作る時に便利だったArray#sampleの覚書

Rubyで開発中、サンプルデータ等を用意する時に役立つメソッドがあったのでメモします。

Arrayクラスのインスタンスメソッドであるsampleメソッドというもので、「配列の中からランダムに返す」という機能です。

[1,2,3].sample
=> 3 # 毎回変わる

真偽値をランダムで返したりすると便利そうです

[true, false].sample
=> true # 毎回変わる

ちなみに引数に整数を渡してあげると、その数の要素数の配列で返ってきます。

[1, 2, 3, 4, 5].sample(3)
=> [4, 2, 1] # 毎回変わる

[1, 2, 3, 4, 5].sample(10)
=> [4, 3, 1, 2 ,5] # 全部取ってくる(順番は変わる)

ローカルでの軽いテストで使ったりする分には役立ちそうです。

Rubyのcoerceメソッドについて

Rubyの勉強していたらNumeric#coerceメソッドというものを見つけたのでメモ

機能

全ての数値オブジェクトに対して使えるメソッドで、引数で与えられた数を自分と同じクラスにして自分とセットで配列で返すものだそうです。

hoge = 1.6
hoge.coerce(5)
=> [5.0, 1.6]

呼び出し元の1.6に引数で与えられた5が変換され、IntegerからFloatになりました。

逆もできるかなーと。

hoge = 2
hoge.coerce(1.6)
=> [1.6, 2.0]

なぜかFloatになってしまった。

なんでやねんと思い、ソースを見たらまさかのC言語が出てきました。大分根っこまできたなあ。

static VALUE
num_coerce(VALUE x, VALUE y)
{
    if (CLASS_OF(x) == CLASS_OF(y))
        return rb_assoc_new(y, x);
    x = rb_Float(x);
    y = rb_Float(y);
    return rb_assoc_new(y, x);
}

ぱっと見た感じどちらもFloat型に変換しているっぽいです(rb_Floatあたり)。 仕様っぽいので、結構各クラスで変換後のクラスは別途定義しているようですね。 まとめてみよう

↓呼び出し元 →引数 Integer Float Rational Complex
Integer Integer Float Float Error
Float Float Float Float Error
Rational Rational Float Rational Complex
Complex Complex Complex Complex Complex

使い道

正直浮かばない

改めてRubyの整数と浮動小数点数についてまとめた

はじめに

基礎からRubyの勉強をし直そうということでプログラミング言語 Rubyをガッツリ読み直していると、普段何気なく使ってる数値も深く書かれているので少しまとめます。

数値について

全ての数値オブジェクトは Numericクラスのインスタンス。整数であったり浮動小数点数であったりすると Integerクラスや Flortクラスのインスタンスになったりする。

種類

整数リテラル

単純に数字を並べればリテラルになる

1234
0
85943

クラスは FixnumBignumの二つで、Fixnumで対応できない大きい値(31ビット幅より上)はBignumになる。

1000000.class
=> Fixnum

100000000000000000000.class
=> Bignum

2進数、8進数、16進数で書くこともできる

  • 2進数
    • 頭に 0b
0b1101
=> 13
  • 8進数
    • 頭に 0
0757
=> 495
  • 16進数
    • 頭に 0x
0xFA
=>250


それぞれ対応していない値を書くとエラーになる

# これらは全てエラー
0b30
0922
0xFG


では8進数等で書いた文字列を to_iするとどうなるか。

'0b1011'.to_i
=>0
'0922'.to_i
=>922
'0xFA'.to_i
=>0

10進数として扱われた。2進数などはリテラルでないと無理っぽい。

浮動小数点数リテラル

いわゆる小数点付きの数値が浮動小数点数。 Floatクラスで表される。

1.02
0.5


指数形式でも書ける。

2.01e8 # 2.01に10の8乗をかけたもの
=> 201000000.0


では2.01e8という文字列を to_fするとどうなるか。

'2.01e8'.to_f
=> 201000000.0

動いた。

ちなみに0.1.1と省略しては書けない

数値の変更について

Rubyの数値データはイミュータブル(変更不可)。 足し算等で数値が変わっているように見えても、それは別オブジェクトが返って来ているにすぎない。

hoge = 1
hoge.object_id
=>3

hoge = hoge + 1
hoge.object_id
=>5

おわりに

整数と浮動小数点数だけでも詳しく見ると結構深いです(まだ把握しきれていない感)。
他にも複素数を表す Complexや 有理数を表す Rationalがあるがそれはまた別の機会にまとめます。

プログラミング言語 Ruby

プログラミング言語 Ruby

  • 作者: まつもとゆきひろ,David Flanagan,卜部昌平(監訳),長尾高弘
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2009/01/26
  • メディア: 大型本
  • 購入: 21人 クリック: 356回
  • この商品を含むブログ (129件) を見る