前面几章已涉及Array,Hash,Proc三种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-八进制 0d-十进制 0x-十六进制 0b-二进制
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 #下划线被约定为.的转换,所以自动去掉。
数字串如果包含(decimal point)小数点或(exponent)指数,则将被转换为Float对象。
1.0e3不可以省去.后的1.e3,因为这样会去调用1对象的e3方法。所认.后面必需跟一个数值。
有理数是两个整数的比,复数也有实数与虚数。这两个都不能用一个串的样式表示,Ruby提供Rational与Complex两个类,调用它们的构造方法,即获取对象。
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(数值的内部原理)
操作符两边如果类型不一样,结果会采用更通用的那个类型来保存,比如混合整型与浮点型,则结果是浮点型,混合浮点型与复数,结果是复数。
除的规则也是一样,只是两个整型相除,结果还是整型:
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
插入串不仅可以是表达式,还可以是一个或多个代码段:
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-ASCII,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
假设需求有三:
- 将第一行数据填充到对应的属性中
- 将以mm:ss格式的时间转换为秒
- 将属性内容的空格trip掉
#下面示例演示上面需求实现的代码 #String#chomp用于去掉串后的分离符如\r\n #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(范围)
三个主要用途: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
相关推荐
《Programming Ruby》是一本关于Ruby编程语言的经典书籍,它的第三章深入探讨了Ruby的基本语法和核心概念。在这一章中,作者介绍了变量、常量、符号、数组、哈希等核心数据类型,以及控制流(条件语句和循环)和方法...
"ruby--.txt"可能是一个文本文件,其中包含了Ruby的代码示例、笔记或者问题解答,通过阅读可以加深对Ruby语法和实践的理解。 "Ruby语言入门教程附实例"和"ruby-mht"文件很可能是包含实例的教程,实践是学习编程的...
1. **面向对象编程(Object-Oriented Programming, OOP)**:Ruby是完全的面向对象语言,每个值都是一个对象,包括基本类型如整数、字符串和布尔值。类是创建对象的蓝图,实例化一个类就能创建一个新的对象。理解类...
首先,Ruby的核心概念是面向对象编程(Object-Oriented Programming, OOP)。在Ruby中,一切都是对象,包括基本的数据类型如数字、字符串和布尔值。理解这一点至关重要,因为这意味着你可以对任何东西调用方法,这极...
"programming_language:编程语言学习笔记"这一主题旨在整理和探讨各种编程语言的关键特性、语法结构以及在实际开发中的应用。 首先,编程语言可以分为几大类别,如低级语言(机器语言和汇编语言)和高级语言(如C,...
java俄罗斯框源码开源社会大学 计算机科学课程 罗伯特·福克 核心模块 C100 - 计算机科学课程简介 涵盖的主题: computation imperative programming ...笔记 ...programming ...Ruby 代码 班级 笔记 代码 地
Ruby, Algorithms, and so on in a few days or hours. The Amazon advanced search for [ and found 512 such books. Of the top ten, nine are programming books (the other is about bookkeeping). Similar ...
RxSwift合并备忘单 这是一份对苹果新的框架感兴趣的开发人员的。 它基于以下博客文章: : RxSwift ... 这似乎是隐藏@State的类型 可完成的 :cross_mark: 复合一次性 :cross_mark: Connectabl
在“zellytozelly-main”这个文件名中,如果没有更多的上下文信息,我们可以假设它可能是一个项目的主分支或者主要代码仓库,包含着开发者的学习笔记、代码示例或实际项目的源代码。 总之,“zellytozelly”项目...
1. **基础语言和框架**:后端开发通常始于学习一种或多种编程语言,如Python、Java、Ruby或Node.js。每种语言都有其特性和用途,例如Python适合数据分析和快速开发,而Java则因其跨平台能力和企业级应用而流行。 2....
"xjl_fullstack:前端 全栈学习" 的标题和描述表明这是一个关于前端和全栈开发的学习资源,可能是某个教程、笔记或者代码仓库。尽管没有提供具体的压缩包内容,我们可以根据标签"HTML"以及文件名"xjl_fullstack-main...