参考宝岛台湾Ruby社区的教程:http://ihower.tw/training/ruby-tutoral.html
感觉挺容易上手的。自己学着敲一便,有一个感性认识。语言是需要实践的学习过程的。
我们用irb这种交互式的工具来学习Ruby语言。
使用方法很简单,打开command窗口,输入irb,看到下面的提示符就表示成功打开了irb环境。
irb(main):001:0>
1)来一个世界上最简单的输出:
irb(main):001:0> "hello world" => "hello world"
2)IRB 告诉我们最后的叙述执行结果。如果我们需要输出 “Hello World” 还需要多一行:
irb(main):002:0> puts "hello world" hello world => nil
puts 是 Ruby 的基本输出指令。但是什么是 => nil 呢? 那是那一行叙述的执行结果。 puts 总是回传 nil,nil 在 Ruby 中表示一个绝对的空值。
3)接下来把irb当计算机来用一用
irb(main):003:0> 3*23 => 69 irb(main):004:0> 3**2 => 9 irb(main):005:0> 3.sqrt NoMethodError: undefined method `sqrt' for 3:Fixnum from (irb):5 from (null):0 irb(main):006:0> Math.sqrt(2) => 1.4142135623731 irb(main):007:0>
*是乘法,**是乘方,sqrt是方根。方根的使用不能写成“3.sqrt”,要用Math Modules来实现。
irb(main):011:0> a = 3**2 => 9 irb(main):012:0> b = 4**2 => 16 irb(main):013:0> Math.sqrt(a+b) => 5.0
再试验一下Math Modules,当然里面还有其他的如sin tan等计算方法,这里不做更多试验了,需要的时候再查文档即可。
4)下面准备些一个方法,一边重复执行hello world方法。
irb(main):016:0> def hello irb(main):017:1> puts "hello world" irb(main):018:1> end
很简单,用def和end来表明方法范围。
如果一行只有一条执行语句则不需要结束符。
Ruby 回应 => nil 告诉我们它知悉了这个方法定义。
5)既然定义了方法,那么就调用一下看看吧。
irb(main):019:0> hello hello world => nil irb(main):020:0> hello() hello world => nil
因为方法没有参数,所以可以省略()。
返回结果nil对于我这个学java的来说有点不太适应。O(∩_∩)O~
6)接下来进一步修改方法,让他可以对某个人说hi。也就是给方法加参数。
irb(main):025:0> def hello(name) irb(main):026:1> puts "hello #{name}" irb(main):027:1> end => nil irb(main):028:0> hello("jack") hello jack => nil
这里说明一下单引号和双引号的区别(当构造字符串文本时):
单引号不对字符串做任何处理(及特殊情况除外)。
双引号则会查找其中的替换串(substitution)--以反斜杠开头的字符序列,并将其替换成对应的二进制值。比如\n会被替换成回车。
表达式插补(expression interpolation),#{expression }序列会被替换成expression 表达式的值,就如上面的例子中#{name}被替换成name表达式的值“jack”。
7)字符串内联
irb(main):029:0> def hello(name) irb(main):030:1> puts "hello #{name.capitalize}" irb(main):031:1> end => nil irb(main):032:0> hello("jack") hello Jack => nil
很明显,替换序列中准许写复杂表达式的。这里通过表达式将传入参数的首字母变成了大写。
Ruby中一切皆对象,对象.方法名是比较常用的使用方法。
8)给方法参数加个默认值看看
irb(main):001:0> def hello(name= "world") irb(main):002:1> puts "hello #{name}" irb(main):003:1> end => nil irb(main):004:0> hello "jack" hello jack => nil irb(main):005:0> hello hello world => nil
在没有传递任何参数的情况下,name使用了默认值world。
这里体现了另外一个语法细节,省略调用方法的括号。
9)创建一个接待员,来学习方法内部变量及方法的使用方法。
irb(main):007:0> class Greeter irb(main):008:1> def initialize(name = "world") irb(main):009:2> @name = name irb(main):010:2> end irb(main):011:1> def say_hi irb(main):012:2> puts "hi #{@name}" irb(main):013:2> end irb(main):014:1> def say_bye irb(main):015:2> puts "bye #{@name}, come back soon." irb(main):016:2> end irb(main):017:1> end => nil
在Greeter初始化的时候,给实例变量@name进行赋值,默认值为“world”,并且定义了say_hi和say_bye两个方法,在方法内可以调用实例变量@name。
创建之后就可以使用这个类了。
irb(main):018:0> g = Greeter.new("jack") => #<Greeter:0x2d959a0 @name="jack"> irb(main):019:0> g.say_hi hi jack => nil irb(main):020:0> g.say_bye bye jack, come back soon. => nil
首先创建一个类的实例g,并且记住了名字jack。然后调用实例的方法say_hi和say_bye。
在创建实例的时候,在返回值上看到了实例变量,我们是否可以直接访问呢?试验一下:
irb(main):021:0> g.@name SyntaxError: compile error (irb):21: syntax error, unexpected tIVAR from (irb):21 from :0
看来时不能直接访问了。说明实例变量是隐藏内class内部的,OO的封装思想在这里一览无余。
10)我怎么知道这个类有多少个方式是我可以使用的呢?
irb(main):022:0> Greeter.instance_methods => ["inspect", "tap", "clone", "public_methods", "__send__", "instance_variable_ defined?", "equal?", "freeze", "extend", "send", "methods", "say_hi", "hash", "d up", "instance_variables", "eql?", "object_id", "instance_eval", "id", "singleto n_methods", "say_bye", "taint", "frozen?", "instance_variable_get", "instance_of ?", "to_a", "to_enum", "type", "instance_exec", "protected_methods", "==", "===" , "instance_variable_set", "kind_of?", "respond_to?", "to_s", "hello", "enum_for ", "class", "method", "__id__", "tainted?", "=~", "private_methods", "untaint", "nil?", "display", "is_a?"]
晕,好多,我明明只创建了两个,一个say_hi一个是say_bye。
这里是Greeter的所有方法,包括集成自父类的方法等等。想查看自己的方法怎么看?加一个false就可以了。
irb(main):023:0> Greeter.instance_methods(false) => ["say_hi", "say_bye"]
接下来看看Greeter对哪些方法有反应吧
irb(main):024:0> g.respond_to?("name") => false irb(main):025:0> g.respond_to?("say_hi") => true irb(main):026:0> g.respond_to?("say_bye") => true
看结果就知道了,不需要更多说明了。至于respond_to这个奇妙的方法,后面还有更多妙用,我可能会在后面另起一篇文章来学习一下。
11)上面提到了,实例变量@name是无法直接通过外部访问的,这不仅让我想起了java的set,get方法群,虽然现代IDE工具有很多可以自动生成,但是依然麻烦无比。
让咱们一起学习一下ruby是怎么解决这个问题的吧。
修改类:
irb(main):027:0> class Greeter irb(main):028:1> attr_accessor :name irb(main):029:1> end
通过name方法对实例变量(attr)进行访问。attr_accessor
会定义两个方法,name用来取值,name=用来赋值。
irb(main):030:0> g = Greeter.new("jack")#生成类实例 => #<Greeter:0x2e92e40 @name="jack"> irb(main):031:0> g.respond_to?("name")#查看是否有name方法,这个方法相当于java的getXXXX => true irb(main):032:0> g.respond_to?("name=")#查看是否有name=方法,这个方法相当于java的setXXXX => true irb(main):033:0> g.say_hi hi jack => nil irb(main):034:0> g.name = "lily" => "lily" irb(main):035:0> g => #<Greeter:0x2e92e40 @name="lily"> irb(main):036:0> g.name => "lily" irb(main):037:0> g.say_hi hi lily => nil
使用起来比java的setget可方便多了。因为还没有使用到IDE工具,如果这部分也可以自动生成当然就更好了。
到此为止,irb的使用应该熟悉了,也是跟他说byebye的时候了,irb不太适合写比较复杂比较长的程序。
下一章,我们一起用rb文件来体验ruby世界了。