Programming Ruby(読書ノート)-6章(標準タイプ)

8742 ワード

前述の章では,Array,Hash,Procの3種類のRubyが提供するタイプについて述べた.この章ではnumbers,strings,rangesおよび正規表現について説明します.
 
6.1数値タイプ
Rubyはintegers(整数)、floating-point浮動小数点型、rational(有理数)、complex numbers(複数)をサポートします.整数型は任意の長さ(メモリ空間の長さ)である、通常の整数型を超える部分記憶タイプはBignumのインスタンスであり、一部を超えない部分はFixnumのインスタンスであり、このような変換Rubyは自動的に変換する.
#        ,    Bignum
num = 10001
4.times do
  puts "#{num.class}: #{num}"
num *= num
end
produces:
Fixnum: 10001
Fixnum: 100020001
Fixnum: 10004000600040001
Bignum: 100080028005600700056002800080001

接頭辞識別数進表現:0-8進0 d-10進0 x-16進0 b-バイナリ
123456      => 123456 # Fixnum
0d123456  => 123456 # Fixnum
123_456    => 123456 # Fixnum - underscore ignored
-543           => -543 # Fixnum - negative number
0xaabb      => 43707 # Fixnum - hexadecimal
0377          => 255 # Fixnum - octal
-0b10_1010 => -42 # Fixnum - binary (negated)
123_456_789_123_456_789 => 123456789123456789 # Bignum
#       .   ,      。

数字列に小数点または指数が含まれている場合は、Floatオブジェクトに変換されます.
1.0 e 3は省くことができない.後の1.e 3,これにより1オブジェクトのe 3メソッドが呼び出されるからである.承认後に数値を付けなければなりません.
 
有理数は2つの整数の比であり,複素数にも実数と虚数がある.どちらも1つの列のスタイルで表すことはできません.RubyはRationalとComplexの2つのクラスを提供し、それらの構築方法、すなわちオブジェクトを取得します.
Rational(3, 4) * Rational(2, 3) # => (1/2)
Rational("3/4") * Rational("2/3") # => (1/2)

Complex(1, 2) * Complex(3, 4) # => (-5+10i)
Complex("1+2i") * Complex("3+4i") # => (-5+10i)

すべての数値タイプはオブジェクトであり、num.absなどの複数の方法がその絶対値を取得します.
#              
some_file.each do |line|
  v1,v2 = line.split
  print Integer(v1) + Integer(v2), "  " #        
end
produces:
7 11 15

 
How Numbers Interact(数値の内部原理)
オペレータの両側にタイプが異なる場合、結果はより一般的なタイプで保存されます.たとえば、ブレンド整数型と浮動小数点型では、結果は浮動小数点型、ブレンド浮動小数点型と複数、結果は複数です.
除外のルールも同じですが、2つの整数を除いただけで、結果は整数です.
1.0 / 2 # => 0.5
1 / 2.0 # => 0.5
1 / 2 # => 0

mathnモジュールが導入された場合、22/7という有理数構造で表すことができる.
 
循環数値タイプ
# Numberic        ,  :
3.times { print "X "}
1.upto(5) {|i| print i, " "}
99.downto(95) {|i| print i, " "}
50.step(80, 5) {|i print i, " "|}

produces:
X X X 1 2 3 4 5 99 98 97 96 95 50 55 60 65 70 75 80

反復器は{}が付いていない場合はEnumeratorオブジェクトを返します.例:
10.downto(7).with_index {|num, index| puts "#{index}: #{num}"}
produces:
0: 10
1: 9
2: 8
3: 7

 
6.2 strings
# JS       
'escape using "\\"' # => escape using "\"
'That\'s right' # => That's right

#{expr}は、exprがグローバル変数、クラス変数、またはインスタンス変数である場合、無視できる代替値を表します.
# expr      
"Seconds/day: #{24*60*60}" # => Seconds/day: 86400
"#{'Ho! '*3}Merry Christmas!" # => Ho! Ho! Ho! Merry Christmas!
"Safe level is #$SAFE" # => Safe level is 0
#       ,        
#$SAFE     0

挿入列は、式だけでなく、1つ以上のコードセグメントであってもよい.
puts "now is #{ def the(a)
                              'the' + a
                           end
                           the('time')
                         } for all bad coders..."
produces:
now is the time for all bad coders...

また、%q%Q here寸法を使用して文字列を構築することもできます.
%q/general single-quoted string/ # => general single-quoted string
%Q!general double-quoted string! # => general double-quoted string
%Q{Seconds/day: #{24*60*60}} # => Seconds/day: 86400
q Q       
%!general double-quoted string! # => general double-quoted string
%{Seconds/day: #{24*60*60}} # => Seconds/day: 86400
#%q      ,%Q      。
#q Q      ,   [ { (,     ] } ),           。

 ---------------using a here document-----------
#  END_OF_STRING      ,            
string = <<END_OF_STRING
The body of the string is the input lines up to
one starting with the same text that followed the '<<'
END_OF_STRING #        

<<の後に-を追加すると、最初の列に配置されたルールに従わなくてもいいです.
string = <<-END_OF_STRING
            The body of the string is the input lines up to
            one starting with the same text that followed the '<<'
            END_OF_STRING

複数のhere documentもあります
print <<-STRING1, <<-STRING2
Concat
STRING1
       enate
       STRING2

produces:
Concat
      enate

注意:スペースは自動的にtripされません
 
Strings And Encodings
1.9デフォルトはUS-ACSCII、2.0デフォルトはUTF-8
#      
plain_string = "dog"
puts RUBY_VERSION
puts "Encoding of #{plain_string.inspect} is #{plain_string.encoding}"

 
Working with Strings
次の例では、Stringを使用する方法について説明します.次のようなデータファイルがあるとします.
ut_stdtypes/songdata
song’s duration, the artist, and the title
/jazz/j00132.mp3  | 3:45 | Fats Waller         | Ain't Misbehavin'
/jazz/j00319.mp3  | 2:58 | Louis Armstrong     | Wonderful World
/bgrass/bg0732.mp3| 4:09 | Strength in Numbers | Texas Red

3つの要件があるとします.
  • 対応する属性に1行目のデータを埋め込む
  • mm:ss形式の時間を秒
  • に変換
  • 属性内容のスペースtripを削除
  • #               
    #String#chomp           \r
    #String#squeeze ! ? Song = Struct.new(:title, :name, :length) File.open("songdata") do |song_file| songs = [] song_file.each do |line| file, length, name, title = line.chomp.split(/\s*\|\s*/) name.squeeze!(" ") mins, secs = length.scan(/\d+/) songs << Song.new(title, name, mins.to_i*60 + secs.to_i) end puts songs[1] end

     
    6.3 Ranges(範囲)
    3つの主な用途:sequences(シーケンス)、conditions(条件)、intervals(区間)
     
    Ranges as Sequences
    1..10
    'a'..'z'
    0...'cat'.length
    #..       ;...     (  )
    #  range,  to_a     ,to_enum   Enumerator
    (1..10).to_a # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    ('bar'..'bat').to_a # => ["bar", "bas", "bat"]
    enum = ('bar'..'bat').to_enum
    enum.next # => "bar"
    enum.next # => "bas"
    ############
    #Range          ,        
    digits = 0..9 #    Range
    digits.include?(5) # => true
    digits.max # => 9
    digits.reject {|i| i < 5 } # => [5, 6, 7, 8, 9]
    digits.inject(:+) # => 45

    私たちは自分で定義したクラスにRangeのこのようなsequence用途をサポートさせることができ、succメソッドを実現して次のオブジェクトを返すことと、compareインタフェースに似た<=>メソッドを実現することです.
    class PowerOfTwo
      attr_reader :value
      def initialize(value)
        @value = value
      end
      def <=>(other)
        @value <=>other.value
      end
      def succ
        PowerOfTwo.new(@value + @value)
      end
      def to_s
        @value.to_s
      end
    end
    p1 = PowerOfTwo.new(4)
    p2 = PowerOfTwo.new(32)
    puts (p1..p2).to_a
    produces:
    4
    8
    16
    32

     
    Ranges as Conditions
     
    #             start,      end
    while line=gets
      puts line if line=~/start/..line=~/end/
    end
     
     
    Ranges as Intervals
    テスト要素は指定した区間です.==オペレータの使用
     
    (1..10) === 5       # => true
    (1..10) === 15      # => false
    (1..10) === 3.14159 # => true
    ('a'..'j') === 'c'  # => true
    ('a'..'j') === 'z'  # => false

     
    #      9.5
    car_age = gets.to_f
    case car_age
    when 0...1
      puts "Mmm.. new car smell"
    when 1...3
      puts "Nice and new"
    when 3...10
      puts "Reliable but slightly dinged"
    when 10...30
      puts "Clunker"
    else
      puts "Vintage gem"
    end
    
    produces:
    Reliable but slightly dinged