たのしいRuby 第5版

図書館にあった たのしいRuby 第5版 を読む。
手元の本は第2版で1.8が対象だったのだが、1.9以降のStringの仕様変更の理解がずっと浅いように感じているので、第3部を中心に落ち穂拾い的にあちこち読んで見る。
以下気になった点のメモ。1.8でもあったものかどうかは調べていないが、知らないことが多い。

第12章 数値(Numeric) クラス

これまで有理数複素数を使う機会はなく、スルーしていた部分。

有理数複素数
r = Rational(2, 3)
p r.to_f
p [r.numerator, r.denominator]
r2 = 1.3r
p r2
c1 = Complex(1, 2)
c2 = 3i
c = c1 + c2
p c
p [c.real, c.imaginary]

数値の型変換 Numeric#round

四捨五入する位置を指定する引数がある

p 12.34.round(1)
p 12.34.round(-1)
p 12.34.round

第13章 配列(Array) クラス

Array.new あれこれ。
Array.new       # => []
Array.new(3)    # => [nil, nil, nil]
Array.new(3, 0) # => [0, 0, 0]
Array.new(3, [0, 0, 0])    # => 各要素は同じオブジェクトを指す
Array.new(3) { [0, 0, 0] } # => 各要素は別のオブジェクト
Array.new(3) { |i| i * 2 } # => [0, 2, 4]
Array#values_at
a = %w(a b c d e)
a.values_at(0, 2, 4) # => ["a", "c", "e"]

第14章 文字列(String) クラス

ヒアドキュメント
def hear_test
  s1 = <<EOS
    string
EOS
  s2 = <<-EOS
    string
  EOS
  s3 = <<~EOS
    string
  EOS
  p s1, s2, s3
end

hear_test

<<~ は 2.3.0から追加とのこと

全角英数を半角へ、かつ半角カナを全角カナへ

仕事でよく出てくるパターン。NKFでうまくいく。

s = "これがコレガコレガABC123 abc123"
p s                   # => "これがコレガコレガABC123 abc123"
p NKF.nkf('-wZ1X', s) # => "これがコレガコレガABC123 abc123" 

第15章 ハッシュ(Hash) クラス

Hash#store, Hash#fetch
h = Hash.new('')
h[:p]                  # => ''
h.fetch(:p)            # => KeyError
h.fetch(:p, '(undef)') # => '(undef)'
デフォルト値
  • Hash.new(value)
  • Hash.new { |hash, key| }
  • Hash#fetch(key, value)

Hash.new にブロックを渡す例

h1 = Hash.new('')
h2 = Hash.new do |hash, key|
  hash[key] = key.upcase
end

第16章 正規表現(Regexp) クラス

Unicode文字プロパティを使った文字クラス指定
/\p{Hiragana}/
/\p{Katakana}/
/\p{Han}/

使うことはないだろうと思う。

マッチ結果

$&, $1 ではなく Regexp.last_match を使うのも良さそう。
(Matchdata#to_a)

第17章 IOクラス

Fileオブジェクトを作成せずに読み書きする方法

File.read('in.txt', { encoding: 'utf-8' }) # option のハッシュも使えるようだ
File.write('out.txt', '漢字まじり', { encoding: 'utf-8' }) 

File.binread('in.bin')                     # バイナリファイルの場合
File.binwrite('out.bin', '漢字混じり')

他のコマンドとのやり取り

第18章 FileクラスとDirクラス

実際に使うときにヘルプを見れば良し。

第19章 エンコーディング(Encoding)クラス

1.8から1.9で変化の大きかったところ。
ファイルを扱う際は気をつけているが、ARGVのエンコーディング変換は時々忘れる。

第20章 TimeクラスとDateクラス

実際に使うときにヘルプを見れば良し。

第21章 Procクラス

Proc, ラムダ式について メタプログラミングRuby 第2版 を読むほうが良い。

pdf ファイルからイメージファイルを取り出す(ruby, poppler)

ruby で pdfファイル内のテキスト、図の情報を取り出すのをどうするか。
簡単なのは poppler みたいなので、試して見る。
poppler 自体は他の gem のインストール時に勝手に入っているので問題なし。
ただし日本語を含むものはエラーが出るので poppler-data が必要のようだ。

Windows上のRubyで日本語PDFを読むためにpoppler-dataをインストールする方法 - アイデアの甕 を参考にさせてもらった。
Poppler の下の方にある、poppler-data のリンク
(本日現在で https://poppler.freedesktop.org/poppler-data-0.4.7.tar.gz )を解答したフォルダを
poppler にリネームして、poppler-gem の下に置けば良い。

こちらの環境では次のフォルダの下ということにになる。
C:\Programs\ruby\lib\ruby\gems\2.3.0\gems\poppler-3.0.8-x86-mingw32\vendor\local\share

テキストの取り出しは至って簡単。
イメージの取り出しは、pdf に格納されているままということではなく、write_to_pngpng ファイルとして書き出すことになる。
image_mapping メソッドがページ内のイメージ数の取得に使えそうだが、[]を返すので、nil になるまでループを回すしかなさそう。

require 'poppler'

if ARGV.empty?
  puts 'usage: rb get_image.rb file [files...]'
  exit
end

ARGV.each_with_index do |file, file_num|
  file = file.encode 'utf-8'
  doc = Poppler::Document.new file
  doc.pages.each_with_index do |page, page_num|
    puts "file: #{file}, page: #{page_num}"
    image_num = 0
    loop do
      img = page.get_image image_num
      break unless img
      filename = "#{File.basename(file, '.*')}_#{page_num}_#{image_num}.png"
      img.write_to_png filename
      image_num += 1
    end
  end
end

Rubyの組み込みクラスの一覧を表示してみる

組み込みクラスの一覧を表示してみたいと思い立った。

考えたのは

  1. Objectの定数一覧取得
  2. それぞれの定数からクラスを得る
  3. そのクラスがClassであれば、組み込みクラス
[8] pry(main)> puts Object.constants.select { |x| Kernel.const_get(x).class == Class }
Object
Module
Class
BasicObject
NilClass
Data
TrueClass
FalseClass
Encoding
String
Symbol
Exception
SystemExit
SignalException
Interrupt
StandardError
TypeError
ArgumentError
IndexError
KeyError
RangeError
ScriptError
SyntaxError
LoadError
NotImplementedError
NameError
NoMethodError
RuntimeError
SecurityError
NoMemoryError
EncodingError
SystemCallError
UncaughtThrowError
ZeroDivisionError
FloatDomainError
Numeric
Integer
Fixnum
Float
Bignum
Array
Hash
Struct
RegexpError
Regexp
MatchData
Range
IOError
EOFError
IO
File
Dir
Time
Random
Proc
LocalJumpError
SystemStackError
Method
UnboundMethod
Binding
Enumerator
StopIteration
RubyVM
Thread
ThreadGroup
ThreadError
ClosedQueueError
Mutex
Queue
SizedQueue
ConditionVariable
Fiber
FiberError
Rational
Complex
TracePoint
StringIO
Monitor
Delegator
SimpleDelegator
PrettyPrint
PP
Pry
Slop
Tempfile
Pathname
Insertion
SymbolHash
OpenStruct
OptionParser
OptParse
Logger
StringScanner
ScanError
=> nil

うまくいっている模様。*Errorは例外クラスと
Errorは例外クラス。
普段見慣れないものもかなりある。

Windows版Rubyでp メソッドが文字化けする件の回避(-Uオプション)

いわゆるprintfデバッグに相当する pメソッドなのだが、漢字が正しく表示されない。
例えば

class Tel
  def initialize(number, name)
    @number = number
    @name   = name
  end
end

kyoto = Tel.new('075', '京都市')
p kyoto

を実行すると、ruby 1.9からだったと思うが、

> ruby  tel.rb                                            
#<Tel:0x2dcb764 @number="075", @name="\u4EAC\u90FD\u5E02">

のように悲しい結果になる。
試行錯誤の結果、どうやらEncoding.default_internal の問題の模様。
実際に

def show_enc                                               
  %i(default_external default_internal).each do |enc|      
    puts "Encoding.#{enc} => #{Encoding.send(enc).inspect}"
  end                                                      
end                                                        

class Tel
  def initialize(number, name)
    @number = number
    @name   = name
  end
end

kyoto = Tel.new('075', '京都市')
p kyoto

show_enc

とすると

> ruby tel.rb                                             
#<Tel:0x2dbb79c @number="075", @name="\u4EAC\u90FD\u5E02">
Encoding.default_external => #<Encoding:Windows-31J>      
Encoding.default_internal => nil                                                   

となっている。
そこで、-U オプションを付けてやると

> ruby -U tel.rb                                     
#<Tel:0x2f1ab10 @number="075", @name="京都市">          
Encoding.default_external => #<Encoding:Windows-31J> 
Encoding.default_internal => #<Encoding:UTF-8>       

と幸せになれるという次第。
環境変数RUBYOPTに-Uを設定しておくと手間もかからない。

ただし、Rubyinstallerのruby.exeだと何故かエラーになることがある。
環境にもよるようだが、ASRだと今のところ問題なし。

廉恥 - 今野敏

いつもの今野敏
出てくる人物像は似通ったものだが、それはそれで良し。

中ほどに出てくる

昔は、「恥を知れ」と、よく言われたものだ。それが日本人の美徳だったと思う。
罪を犯すかどうかについて、一神教の世界では「神が見ている」という抑止装置があると言われる。
日本では、「恥を知る」という精神が同様の抑止装置であったのではないだろうか。

という下りは、一神教というかキリスト教の特徴でよく出てくる話か。
欧米では宗教(キリスト教)が人の精神構造に与える影響が大きいとか。

廉恥

廉恥

陽気なギャングが地球を回す - 伊坂幸太郎

久しぶりの伊坂幸太郎
各節の最初にある辞書がなかなかおもしろい。

陽気なギャングが地球を回す (ノン・ノベル)

陽気なギャングが地球を回す (ノン・ノベル)

凍りの掌 - おざわゆき

絵柄と内容とギャップが大きい。

第二次大戦末期におけるソ連の日本に対する動きは

  • 日ソ不可侵条約を一方的に破棄
  • 日本の占領地へ侵攻。北方領土もその対象
  • 捕虜を強制労働させていた

のようなおぼろげな知識しかないのだが、国際法の常識(といったものがあるとして)から見て、避難されてしかるべき内容ではないかと思う。
しかし、戦勝国の一つであったことから、その不適切さは無視されているのか。

凍りの掌

凍りの掌