概括、ruby程序由一个或多个ruby源文件组成,源文件由模块组成,模块内部有控制结构、类对象、方法、及表达式等元素,下面就按照这个思路来总结ruby的程序组织结构。

一、源文件

1.1、文件包含

#file1.rb 
inc_path=$0.sub(/\/\w+\.rb/,"") #获取当前路径的目录 
$:.insert(-1,inc_path) #将当前路径加入到load路径数组 
       
require "file2.rb" 
require "file2.rb" #require包含文件只会被导入一次 
       
load "file3.rb" 
load "file3.rb" #每次load都会无条件再次导入文件 
       
       
#file2.rb 
print "file2.rb is included\n"  
       
       
#file3.rb 
print "file3 is included\n"


1.2、源文件执行顺序

#coding=utf-8   
=begin 
这里是 
多行注释 
=end 
       
END{print "end1\n"}   
END{print "end2\n"}   
#END块的执行顺序与出现顺序相反   
       
print "text\n"   
          
BEGIN{print "begin1\n"}   
BEGIN{print "begin2\n"}   
#BEGIN块的执行顺序与出现顺序相同   
#BEGIN-TEXT-END 
       
#__END__开头的行后面的内容被忽略 
__END__ 
print "no_text\n"



1.3、源文件书写规则

         ◆大小写敏感

         ◆换行符后只能有空白符,并且都会被忽略

         ◆类和模块及常量名要以大写字母开头,变量以小写字母或者unicode开头

二、模块

#module1.rb 
inc_path=$0.sub(/\/\w+\.rb/,"") #获取当前路径的目录 
$:.insert(-1,inc_path) #将当前路径加入到load路径数组 
   
require "module2.rb" 
   
print Mymod::VAR1,"\n" 
Mymod.out 
   
include Mymod #把Mymod导入到当前名字空间 
print VAR1 
   
   
#module2.rb 
print "module2.rb is included\n" 
   
module Mymod 
    var1=99  #模块内的变量 
    VAR1=100 #模块内的常量 
       
    print "Mymode is included,var1 is ",var1,"\n" 
       
    def Mymod.out #模块内的方法必须加上模块名 
        print "Mymod.out run\n" 
    end 
end



三、控制结构



ruby的控制结构和其他语言一样无非就是顺序,分支及循环,但写法上相当的灵活。

3.1、分支结构之if


#if.rb 
num=100   
if (num>200) #可以用unless进行条件取反   
  print "num>200\n"   
elsif num>100  #if和elsif和后面的代码块必须有换行符或者分号或者then来隔离,else不需要 
  print "num>100\n"   
else   
  print "num<=100\n" #此句执行   
end   
       
print "num<=100\n" if num<=100 #if语句可后置
puts (if num==100;"100";end) #if语句也是表达式所以有返回值

3.2、分支结构之case

num=100 
   
str1=
case 
    when num>200 then "num>200" 
    when num>100 then "num>100" 
    else "num<=100" #else不使用then 
end 
   
print str1,"\n" 
   
   
case num 
    when 201 then print "num>200"
    print 101 when num>100 
    else print "num<=100" 
end



3.3、循环结构

num=1 
   
while num<5 #反义词until ,和code的分隔符可以是换行符或者分号或者是关键字do
    print num 
    num+=1 
end 
   
print "\n" 
   
arr1=[1,2,3,4,5] 
   
for i in arr1 
    print i 
end


num=1 
loop{ #注意{必须和loop在同一行 
    num+=1 
    next if num==3 #不输出3 
    redo if num==4 #把循环体内此行的前面的语句再执行一遍 
    break if num>5 #大于5则退出循环 
    print num 
} 
#输出25 
#while,until,for也可用next,redo,break



3.4、for..in结构

可以对可迭代对象也就是有each方法的对象使用for..in。

hash1={:first=>1,:second=>2,:third=>3}
 
for key,value in hash1
    print key," ",value,"\n"
end



3.5、异常处理

begin #raise产生异常
    1/0
rescue Exception=>ex #给异常起别名
    puts ex.class,ex.message
else
    puts "no exception"
ensure #无论有没有异常必须执行的语句
    puts "must run!"
end



3.6、控制结构补充 

print "0 is true!" #0也是true 
print "empty string is true!" #""也是true 
#在ruby中只有nil被判断是false



四、方法定义

ruby中的方法支持默认参数,可变参数但不支持关键字参数,可以通过传入散列表来模拟实现,方法的最后一句的执行结果就是其返回值。

4.1、一般方法

def non_para
    puts "this is non_para method"
end
    
def many_para(para1,hash_para,default_para2=2,*dynamic_para3)
    puts "first para is ",para1
    puts "hash para is below:"
    hash_para.each_key{|key|print key,"\t",hash_para[key],"\n"}
    puts "default_para is ",default_para2
    puts "dynamic para is below:"
    for i in dynamic_para3
        print i,","
    end
end
#默认参数和可变参数必须是最后的两个参数
 
non_para()
many_para(1,{:first=>1,:second=>2},3,5,7,9)



4.2、方法的作用范围

        ruby根据方法名来确定方法的作用范围,这样做增加了程序的阅读性。

#coding=utf-8 
   
str1="abcdefg" 
   
def str1.len #对象的方法 
    puts self.length 
end 
   
str1.len 
   
class Person 
    def Person.info #类的方法即静态方法 
        puts "this is a perosn" 
    end 
end 
   
Person.info



4.3、BLOCK

与方法关联的BLOCK为方法提供了可扩展性。可以把方法中的一部分逻辑抽象成BLOCK独立出来,和子程序调用所不同的是,BLOCK是灵活的,也就是说我可以只完成方法的主干部分,有一些逻辑可以根据需要在调用方法时进行扩展。

def func para1 
    localvalue="local value" 
    yield(para1) 
end 
   
func(100){|para1|print "value of para1 is ",para1,"\n"} 
   
func(100)do 
|para1| 
print "double value of para1 is",para1*2,"\n" 
#print local_value 局部变量已不能被继承 
end 
#yield最后一条语句执行结果就是给方法的返回值。



4.4、方法补充

undef

alias

&方法 得到方法的引用,调用时采用 方法引用.call的方式

五、类及对象

5.1、普通的类定义如下

class Person 
    def initialize(name,age)
        @name=name  #类属性必须在类方法中定义 
        @age=age 
    end 
    def name#属性不能直接被访问,必须通过方法接口进行访问 
        @name 
    end 
    def age 
        @age 
    end 
end 
   
p1=Person.new("justsong",28)#会用相同的参数调用initialize 
print p1.name,"\n",p1.age



5.2、类中方法的访问权限默认为public,ruby有和c++类似的权限声明方式。

class Person 
    def initialize(name,age)#属性在initialize中定义 
        @name=name 
        @age=age 
    end 
    def name#属性不能直接被访问,必须通过方法接口进行访问 
        @name 
    end 
private#protected,public 
    def age 
        @age 
    end 
end 
   
p1=Person.new("justsong",28)#会用相同的参数调用initialize 
print p1.name,"\n" 
#print p1.age,private调用将被禁止



5.3、由于属性必须通过方法接口进行访问,所以在书写程序时有些繁琐,可以采用一下的方法进行简写。

class Person 
    attr_reader :name #具有只读权限 
    attr_writer :age #具有只写权限 
    attr_accessor :country #具有读写权限 
    def initialize(name,age,country) 
        @name=name 
        @age=age 
        @country=country 
    end 
end 
   
#其实是ruby自动生成了一些方法 
   
p1=Person.new("justsong",28,"china")#会用相同的参数调用initialize 
   
print p1.name,"\n" 
print p1.country,"\n" 
#print p1.age,会提示未定义相应方法



5.4、ruby的类也具有类变量(静态变量)及类方法(静态方法)

class Person 
    attr_reader :name 
    @@country="china" #静态变量 
    def initialize(name) 
        @name=name 
    end 
    def Person.output #静态方法,经常也有写成self.output的 
        print "country is ",@@country,"\n" 
    end      
end 
   
Person.output 
   
p1=Person.new("zhangsan") 
p2=Person.new("lisi") 
print p1.name,"\n",p2.name



5.5、类的继承

class Person 
    attr_reader :name 
    def initialize(name) 
        @name=name 
    end 
end 
   
class Student < Person 
    attr_reader :grade 
    def initialize(name,grade) 
        super(name)#利用super调用父类同名方法 
        @grade=grade 
    end 
end 
   
s1=Student.new("justsong",10) 
print s1.name,"\n",s1.grade



5.6、嵌套类

直接在类中定义类,或是在类定义时用::指定的类的所属类。