多年前就很想学习一下RUBY,但是一直拖延症爆发,一件简单的事情居然拖了几年,新的一年,下定决心,决定首先花一星期时间把RUBY学习一下.
安装其实没什么可说的,基本参考https://www.ruby-lang.org/en/downloads/安装即可,我个人使用的是Cygwin,基本上在setup的时候勾选了ruby,打开Cygwin直接敲irb就好了.
如果irb可以成功执行,那么这个安装就成功了.
先从随便敲几句ruby语句开始快速入门:
irb(main):001:0> puts 'hello,world'
hello,world
=> nil
irb(main):002:0> language = 'RUBY'
=> "RUBY"
irb(main):004:0* puts "hello,#{language}"
hello,RUBY
=> nil
irb(main):005:0> puts 'hello,#{language}'
hello,#{language}
=> nil
上面这段尝试可以发现:
irb(main):008:0> 4
=> 4
irb(main):009:0> 4.class
=> Fixnum
irb(main):010:0> 4.methods
=> [:to_s, :inspect, :-@, :+, :-, :*, :/, :div, :%, :modulo, :divmod, :fdiv, :**, :abs, :magnitude, ...]
上面这段可以说明更多的问题:
irb(main):012:0> -4.abs
=> 4
irb(main):014:0> 4.equal?4
=> true
irb(main):015:0> -4.abs.equal?4
=> true
irb(main):016:0> -4.equal?4
=> false
irb(main):020:0> 4.instance_of?Fixnum
=> true
irb(main):025:0> 4.!=4.class
=> true
irb(main):027:0> (4.!=4).class
=> FalseClass
irb(main):001:0> 'size'.length
=> 4
irb(main):004:0> 'size'.include?'si'
=> true
irb(main):005:0> "Ruby is a beautiful language".start_with? "Ruby"
=> true
irb(main):006:0> "I can't work with any other language but Ruby".end_with? 'Ruby'
=> true
irb(main):007:0> 'size'.index'i'
=> 1
irb(main):008:0> 'size'.upcase
=> "SIZE"
irb(main):009:0> 'SIZE'.downcase
=> "size"
irb(main):010:0> "ThiS iS A vErY ComPlEx SenTeNcE".swapcase
=> "tHIs Is a VeRy cOMpLeX sENtEnCe"
irb(main):011:0> "I can't work with any other language but Ruby".split(' ')
=> ["I", "can't", "work", "with", "any", "other", "language", "but", "Ruby"]
irb(main):013:0> "I can't work with any other language but Ruby.I am happy.".sub('I','We')
=> "We can't work with any other language but Ruby.I am happy."
irb(main):014:0> "I can't work with any other language but Ruby.I am happy.".gsub('I','We')
=> "We can't work with any other language but Ruby.We am happy."
irb(main):015:0> 'RubyMonk'.gsub(/[aeiou]/,'1')
=> "R1byM1nk"
irb(main):017:0> 'RubyMonk Is Pretty Brilliant'.gsub(/[A-Z]/,'0')
=> "0uby0onk 0s 0retty 0rilliant"
上面这些语句基本列出了主要的字符串操作函数,大多数语句的含义基本都是不言而喻的。有以下少数几点需要注意:
irb(main):031:0> x=3
=> 3
irb(main):032:0> if x==4
irb(main):033:1> puts 'hello'
irb(main):034:1> end
=> nil
irb(main):035:0> unless x == 4
irb(main):036:1> puts 'hello'
irb(main):037:1> end
hello
=> nil
unless需要特殊记忆一下,这个词我们不能理解为除非,应该理解为如果..不(if not),所以unless x == 4我们一定不能理解为除非x等于4,理解为如果x不等于4更合理一些(unless对我来说太奇怪了,我宁愿使用!或者not).
其实在语义简单的情况下,我们也可以使用行模式:
irb(main):038:0> puts 'hello' if not x==4
hello
=> nil
irb(main):039:0> puts 'hello' if x==4
=> nil
irb(main):040:0> puts 'hello' unless x==4
hello
=> nil
irb(main):052:0> puts 'hello' if 0
hello
=> nil
irb(main):053:0> puts 'hello' if true
hello
=> nil
irb(main):054:0> puts 'hello' if 1
hello
=> nil
irb(main):055:0> puts 'hello' if 'ss'
(irb):55: warning: string literal in condition
hello
=> nil
irb(main):056:0> puts 'hello' if false
=> nil
irb(main):058:0> puts 'hello' if nil
=> nil
irb(main):041:0> x
=> 3
irb(main):042:0> x = x-1 until x==1
=> nil
irb(main):043:0> x
=> 1
irb(main):044:0> until x==5
irb(main):045:1> x=x+1
irb(main):046:1> end
=> nil
irb(main):047:0> x
=> 5
上面我们分别展示了until循环的单行模式和块模式写法.
while的用法基本一致:
>> x = x + 1 while x < 10
=> nil
>> x
=> 10
区间大概可以算是Ruby中的一个语法糖。先看下使用:
irb(main):024:0> (0..9)
=> 0..9
irb(main):025:0> (0..9).class
=> Range
irb(main):027:0> (0..9).size
=> 10
irb(main):032:0> (0..9).include?(9)
=> true
irb(main):034:0> (0...9).to_a
=> [0, 1, 2, 3, 4, 5, 6, 7, 8]
irb(main):035:0> (0..9).to_a
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
irb(main):038:0> (0..9).reject{|i|i<5}
=> [5, 6, 7, 8, 9]
irb(main):039:0> (0..3).each do |i| puts i end
0
1
2
3
=> 0..3
irb(main):040:0> (0..3).each{|i| puts i*5}
0
5
10
15
=> 0..3
irb(main):042:0> (0..9).include?3.14
=> true
irb(main):043:0> (0..9).cover?3.14
=> true
irb(main):044:0> ('a'..'z').cover?'ab'
=> true
irb(main):045:0> ('a'..'z').include?'ab'
=> false
irb(main):066:0> 4+'one'
TypeError: String can't be coerced into Fixnum
from (irb):66:in `+'
from (irb):66
from /usr/bin/irb:12:in `'
irb(main):067:0> 4.class
=> Fixnum
从前面的多次实验我们已经很明确,Ruby和C家族的语言一样,是强类型的语言。但是跟其他静态强类型语言又很不相同,看下面的例子:
irb(main):068:0> def add
irb(main):069:1> 4+'one'
irb(main):070:1> end
=> nil
irb(main):071:0> add
TypeError: String can't be coerced into Fixnum
from (irb):69:in `+'
from (irb):69:in `add'
from (irb):71
from /usr/bin/irb:12:in `'
我们使用def定义了一个函数,我们发现在函数体内语句实际上是类型错误的,但是在定义后并没有编译器报错,而是直到执行时,才做了类型检查并且报错。这个概念叫做动态类型,因此Ruby也是一种动态语言。
这对于写程序时会带来一些困扰,因为编译器和工具能捕获的错误变少,更多错误在执行时被暴露。但是,这也带来了更加大的自由,来看下面这段代码:
irb(main):073:0> i=0
=> 0
irb(main):074:0> a=['100',99]
=> ["100", 99, 98.0]
irb(main):075:0> while i < 2
irb(main):076:1> puts a[i].to_i
irb(main):077:1> i=i+1
irb(main):078:1> end
100
99
=> nil
上面这段代码,数组中存储了两个类型不同的值,但是我们不需要进行类型转换,直接就可以调用变量的to_i方法而没有引发编译错误。
我们知道,在面向对象设计思想中,有这样一个重要原则:对接口编码,不对实现编码。思考一下上面的逻辑我们用java如何实现:我们约定一个实现了to_i的接口,不同类来实现这个接口,这些类的实例存入容器中,依次取出,调用它们的to_i方法。
对比上面我们就可以看出区别,Ruby根本就没有定义接口,也没有强制a存储数据的类型,就直接调用了数据的to_i方法!这也就是著名的鸭子类型的概念:一个类型是什么不是取决于它类型的实体,而是他可以做什么。或者我们使用更通俗的谚语来解释:
如果像鸭子一样走路,像鸭子一样呱呱叫,那它就是一只鸭子。
从这点我们可以看出来Ruby是一种相当自由的语言。
第一天的探索就到这里,我们稍微总结一下:
基于第一天的学习写了一个简单的程序,写了一个猜随机数的程序,根据输入来告诉用户猜大了还是猜小了。如果用户输入exit则退出。
puts 'gusse the num(0~9)'
random = rand(10).to_i
while true
i = gets
if i.start_with?'exit'
break
end
if i.to_i==random
puts 'you get the right num!'
break
elsif i.to_i<random
puts 'small!'
else
puts 'big!'
end
end
基本上使用的都是前面提到的知识。需要额外注意的有: