ruby的程序结构介绍
概括、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.rbisincluded\n" #file3.rb print"file3isincluded\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" printMymod::VAR1,"\n" Mymod.out includeMymod#把Mymod导入到当前名字空间 printVAR1 #module2.rb print"module2.rbisincluded\n" moduleMymod var1=99 #模块内的变量 VAR1=100#模块内的常量 print"Mymodeisincluded,var1is",var1,"\n" defMymod.out#模块内的方法必须加上模块名 print"Mymod.outrun\n" end end
三、控制结构
ruby的控制结构和其他语言一样无非就是顺序,分支及循环,但写法上相当的灵活。
3.1、分支结构之if
#if.rb num=100 if(num>200)#可以用unless进行条件取反 print"num>200\n" elsifnum>100 print"num>100\n" else print"num<=100\n"#此句执行 end print"num<=100\n"ifnum<=100#if语句可后置,并且if语句本身也是表达式也具有值 ifnum<=100thenprint"num<100\n"#then可用:替换
3.2、分支结构之case
num=100 str1=\ case whennum>200then"num>200" whennum>100then"num>100" else"num<=100"#else不使用then end printstr1,"\n" casenum when201:print"num>200"#:和then起到相同的作用 print101whennum>100 elseprint"num<=100" end
3.3、循环结构
num=1 whilenum<5#反义词until printnum num+=1 end print"\n" arr1=[1,2,3,4,5] foriinarr1 printi end
num=1 loop{#注意{必须和loop在同一行 num+=1 nextifnum==3#不输出3 redoifnum==4#把循环体内此行的前面的语句再执行一遍 breakifnum>5#大于5则退出循环 printnum } #输出25 #while,until,for也可用next,redo,break
3.4、控制结构补充
print"0istrue!"#0也是true print"emptystringistrue!"#""也是true #在ruby中只有nil被判断是false
四、方法定义
ruby中的方法支持默认参数,可变参数但不支持关键字参数,可以通过传入散列表来模拟实现,方法的最后一句的执行结果就是其返回值。
4.1、一般方法
defnon_para print"thisisnon_paramethod\n" end defmany_para(para1,default_para2=2,*dynamic_para3) print"firstparais",para1,"\n" print"default_parais",default_para2,"\n" foriindynamic_para3 printi,"," end end non_para() many_para(1,3,5,7,9)
4.2、方法的作用范围
ruby根据方法名来确定方法的作用范围,这样做增加了程序的阅读性。
#coding=utf-8 str1="abcdefg" defstr1.len#对象的方法 putsself.length end str1.len classPerson defPerson.info#类的方法即静态方法 puts"thisisaperosn" end end Person.info
4.3、BLOCK
与方法关联的BLOCK为方法提供了可扩展性。可以把方法中的一部分逻辑抽象成BLOCK独立出来,和子程序调用所不同的是,BLOCK是灵活的,也就是说我可以只完成方法的主干部分,有一些逻辑可以根据需要在调用方法时进行扩展。
deffuncpara1 localvalue="localvalue" yield(para1) end func(100){|para1|print"valueofpara1is",para1,"\n"} func(100)do|para1| print"doublevalueofpara1is",para1*2,"\n" #printlocal_value局部变量已不能被继承 end #yield最后一条语句执行结果就是给方法的返回值。
4.5、方法补充
◆可以undef方法名取消方法的定义
◆alias方法名方法别名可以为方法定义不同的名字
◆&方法得到方法的引用,调用时采用方法引用.call的方式
五、类及对象
5.1、普通的类定义如下
classPerson definitialize(name,age)#属性在initialize中定义 @name=name @age=age end defname#属性不能直接被访问,必须通过方法接口进行访问 @name end defage @age end end p1=Person.new("justsong",28)#会用相同的参数调用initialize printp1.name,"\n",p1.age
5.2、类中方法的访问权限默认为public,ruby有和c++类似的权限声明方式。
classPerson definitialize(name,age)#属性在initialize中定义 @name=name @age=age end defname#属性不能直接被访问,必须通过方法接口进行访问 @name end private#protected,public defage @age end end p1=Person.new("justsong",28)#会用相同的参数调用initialize printp1.name,"\n" #printp1.age,private调用将被禁止
5.3、由于属性必须通过方法接口进行访问,所以在书写程序时有些繁琐,可以采用一下的方法进行简写。
classPerson attr_reader:name#具有只读权限 attr_writer:age#具有只写权限 attr_accessor:country#具有读写权限 definitialize(name,age,country) @name=name @age=age @country=country end end #其实是ruby自动生成了一些方法 p1=Person.new("justsong",28,"china")#会用相同的参数调用initialize printp1.name,"\n" printp1.country,"\n" #printp1.age,会提示未定义相应方法
5.4、ruby的类也具有类变量(静态变量)及类方法(静态方法)
classPerson attr_reader:name @@country="china"#静态变量 definitialize(name) @name=name end defPerson.output#静态方法 print"countryis",@@country,"\n" end end Person.output p1=Person.new("zhangsan") p2=Person.new("lisi") printp1.name,"\n",p2.name
5.5、类的继承
classPerson attr_reader:name definitialize(name) @name=name end end classStudent<Person attr_reader:grade definitialize(name,grade) super(name)#利用super调用父类同名方法 @grade=grade end end s1=Student.new("justsong",10) prints1.name,"\n",s1.grade
5.6、嵌套类
直接在类中定义类,或是在类定义时用::指定的类的所属类。