`
Leon.Wood
  • 浏览: 285125 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Ruby笔记-第一天

阅读更多

 注释 #..
局部变量,方法参数,方法名 :小写字母开头或者*_开头
全局变量:$
实例变量:@(后面不可以直接跟数字)
类变量在使用前必须要初始化;全局变量和实例变量如果没有初始化,其值为 nil
类变量:@@
类变量,类方法在 Java 里与之相对应的是 static变量,static方法。
类名 模块名 常量:大写字母开头

常量全用大写的字母,用下划线分割单词。例如:MAX, ARRAY_LENGTH。
类名和模块名用大写字母开头的单词组合而成。例如:MyClass, Person。
方法名全用小写的字母,用下划线分割单词。例如:talk, is_prime?。在Ruby
里,有时将“!”和“?”附于某些方法名后面。惊叹号“!”暗示这个方法具有破坏性,  有可
能会改变传入的参数。问号“?”表示这个方法是一个布尔方法,只会返回 true  或 false。 
变量和参数用小写字母开头的单词组合而成。例如:name, currentValue。
类名、模块名、变量名、参数名最好使用“名词”或者“形容词+名词”。方法名
最好使用“动词”或者“动词+名词”。例如:aStudent.talk  。
----------------------------------------------------------------------------------------------------------------------
■关于数组

$arr=[]    arr[0]=2 #建立一个全局数组 
$arr<<3  #将3作为数组的一个元素加入到arr中

#建立数组
arr1=[] 
arr2=Array.new 
arr3=['4 ','5 ','6 '] 

#数组访问
puts arr[0]            #3 
puts arr.first          #3 
puts arr[arr.length-1]   #9 
puts arr[arr.size-1]     #9 
puts arr.last            #9 
puts arr[-1]             #9 
puts arr[-2]             #8 
print arr[1..3]   ,"\n"    #456 
print arr[-3,2]   ,"\n"   #78      

数组的索引从 0 开始,一直到数组的长度减去 1;负数表示从数组末尾开始的索引;用一对数字来索引数组,第一个数字表示开始位置,第二数字表示从开始位置起的元素数目。
print arr.join(", "),"\n"  意思是:将数组 arr转换成字符串输出,用", "隔开每个元素,并且换行。

#数组的增删改

arr=[4,5,6]      
print arr.join(", "),"\n"                              #4, 5, 6 
 
arr[4] = "m"      		 	#把4 号索引位置元素赋值为"m"           
print arr.join(", "),"\n"                              #4, 5, 6, , m 
print arr[3] ,"\n"     			#打印3 号索引位置元素#nil  
arr.delete_at(3)    			 #删除3号索引位置元素 
print arr.join(", "),"\n"                             #4, 5, 6, m  
arr[2] = ["a","b","c"]   		 #把2号索引位置元素赋值为["a","b","c"] 
print arr.join(", "),"\n"                              #4, 5, a, b, c, m 
print arr[2] ,"\n"   			  #打印2 号索引位置元素 #abc 
arr[0..1] = [7,"h","b"]    		#把 0..1 号元素替换为7,"h","b" 
print arr.join(", "),"\n"                         	 #7, h, b, a, b, c, m  
arr.push("b" )      		 	 #加入元素"b" 
print arr.join(", "),"\n"                         	 #7, h, b, a, b, c, m, b  
arr.delete(["a","b","c"] )  		 #删除元素["a","b","c"] 
print arr.join(", "),"\n"                               #7, h, b, m, b 
arr.delete("b")         		#删除所有元素"b" 
print arr.join(", "),"\n"                               #7, h, m 
 
arr.insert(3,"d")      			  #在3号索引位置插入元素"d" 
print arr.join(", "),"\n"                               #7, h, m, d 
 
arr<<"f"<<2         			#加入元素"f";加入元素2 
print arr.join(", "),"\n"                              #7, h, m, d, f, 2 
arr.pop         			#删除尾元素 
print arr.join(", "),"\n"                             #7, h, m, d, f 
arr.shift       			#删除首元素   
print arr.join(", "),"\n"                              #h, m, d, f 
arr.clear       			#清空数组 arr 
print arr.join(", "),"\n"                              # 

 #数组运算

aaaa=[" aa ",4,5," bb "] 
bbbb=[4,1,3,2,5] 
 
print aaaa + bbbb    ,"\n"        # aa 45 bb 41325 
print aaaa * 2        ,"\n"          # aa 45 bb  aa 45 bb 
print bbbb - aaaa    ,"\n"         #132 
 
#并运算;交运算 
print aaaa | bbbb    ,"\n"        # aa 45 bb 132 
print aaaa & bbbb    ,"\n"      #45 
 
#排序;倒置 
print bbbb.sort       ,"\n"      #12345 
print aaaa.reverse    ,"\n"      # bb 54 aa 

 

-------------------------------------------------------------------------------------------------------------------
■关于输出

@a=16
puts "Hello World"+@a.to_s   #换行输出
puts "#@a"   #输出@a的值
print "a=",@a,"\n"   #a=输出@a的值

  

3.to_s    #将3转换为字符串
p1=Person.new("leon","18") #创建一个对象

一个Ruby的函数会自动返回它所最后赋值的元素.

---------------------------------------------------------------------------------------------------------------------
■关于字符串

str1 = 'this is str1' 
str2 = "this is str2" 
str3 = %q/this is str3/ 
str4 = %Q/this is str4/ 
str5 = <<OK_str 
    Here is string document, str5 
     line one; 
     line two; 
     line three. 
  OK 
OK_str 
 
puts str3 
puts str4 
puts str5 

 

%q  用来生成单引号字符串;%Q用来生成双引号字符串。%q或者%Q后面跟着的是分隔符,可以是配对!  !; /  /; <  >; (  ); [  ]  ;{  };等等。
str5 是一个字符串文档,从 <<和文档结束符的下一行开始,直到遇到一个放置在行首的文档结束符,结束整个字符串文档。
一个数组可以用 join  方法转换成字符串,join( )  内的参数也是一个字符串,用来分隔数组的每个元素,例如:arr.join(", ")。


双引号括起来的字符串会有转义,例如:“\n”  表示换行。
单引号括起来的字符串并不会对字符串作任何解释,你看到的是什么便是什么,有一个例外:单引号字符串里的  单引号 需要转义。

 

在双引号扩起来的字符串中,不仅可以使用各种转义符,而且可以放置任意的Ruby 表达式在 #{   } 之中,这些表达式在使用这个字符串的时候被计算出值,然后放入字符串。

 

def hello(name) 
    " Welcome, #{name} !" 
end 
 
puts  hello("kaichuan")   # Welcome, kaichuan ! 

 

---------------------------------------------------------------------------------------------------------------------------------
■关于正则表达式
匹配一个正则表达式,用“=~”  ,不能用“==”。 “=~”用来比较是否符合一个正
则表达式,返回模式在字符串中被匹配到的位置,否则返回 nil。
不匹配一个正则表达式,用“!~”  ,不能用“!=”。 “!~”用来断言不符合一
个正则表达式,返回 true,flase。  

str="Hello,kaichuan,Welcome!" 
 
puts  str !~ /kaichuan/      # false     
puts  str !~ /a/             # false    
puts  str !~ /ABC/          # true 

  

---------------------------------------------------------------------------------------------------------------------
■一个ruby程序

class  Person   #Person类开始

  def  initialize( name, age=18 ) #初始化(构造)方法开始
    @name = name
    @age = age
    @motherland = "China"
  end     #初始化方法结束

  def  talk    #talk方法开始
        puts "my name is "+@name+", age is "+@age.to_s
    if  @motherland == "China"
      puts "I am a Chinese."
    else
      puts "I am a foreigner."
    end
  end      # talk方法结束

attr_writer :motherland           #setter
attr_accessor:age   #setter and getter
end      # Person 类结束


p1=Person.new("kaichuan",20) #创建一个Person类的实例
p2=Person.new("Ben")
p2.motherland="ABC"  #给matherland属性赋值
p1.talk
p2.talk

 

-------------------------------------------------------------------------------------------

■关于继承

class    Student < Person   #<继承

  def  talk 
        puts "I am a student. my name is "+@name+", age is "+@age.to_s 
  end  # talk方法结束 

end  # Student类结束 

p3=Student.new("kaichuan",25); 
p3.talk 
p4=Student.new("Ben"); 
p4.talk 

--------------------------------------------------------------------------------------------
b="hh"
puts  "b= #{b}"

b = hh

--------------------------------------------------------------------------------------------
■关于方法

有时将“!”和“?”附于某些方法名后面。惊叹号“!”暗示这个方法具有破坏性,  有可能会改变传入的参数。问号“?”表示这个方法是一个布尔方法,只会返回 true  或 false。

你在定义方法的时候,在最后一行可以显式地 return  某个值或几个值,但却不是必须的。 Ruby  方法的最后一行语句如果是表达式,表达式的值会被自动返回;最后一行语句如果不是表达式,就什么也不返回。

Ruby中圆括号常常被省略,看程序 E5.5-1.rb
#E5.5-1.rb   

def  talk name 
  "Hi! " + name 
end 
 
puts talk "kaichuan"       #Hi! kaichuan 
puts talk("kaichuan")      #Hi! kaichuan 
puts (talk "kaichuan")        #Hi! kaichuan 
puts (talk("kaichuan"))     #Hi! kaichuan 

---------------------------------------------------------------------------------------------------
■ruby对可变参数的支持

def sum( *num ) 
    numSum = 0 
     num.each { |i| numSum+=i } 
     return  numSum 
end 
puts sum()                   #0 
puts sum(3,6)                #9 
puts sum(1,2,3,4,5,6,7,8,9)     #45  

 

 ----------------------------------------------------------------------------------------------------
■关于重写-同一个类中(不同类的同java)   ruby只有重写没有重载

def talk (a) 
    puts "This is talk version 1."     
end   
 
def talk (a,b=1) 
    puts "This is talk version 2."     
end   
 
talk (2)          # This is talk version 2. 
talk (2,7)        # This is talk version 2. 

总是写在后面的方法被执行。

------------------------------------------------------------------------------------------------------
■使用super来增强父类功能

class Person   
   def talk(name) 
        print "my name is #{name}." 
  end  
end 
 
class Student < Person     
  def talk(name) 
    super         print "and I'm a student.\n" 
  end   
end 

 

 ------------------------------------------------------------------------------------------------------

■单例方法
在 Ruby里,可以给具体的实例对象添加实例方法,这个方法只属于这个实例
对象,我们把这样的方法称之为单例方法。
看程序  E6.4-1.rb  :

#E6.4-1.rb   
class Person   
  def talk 
    puts "Hi! "    
  end   
end 
 
p1=Person.new 
p2=Person.new 
 
def  p2.talk        #定义单例方法p2.talk 
        puts "Here is p2. "       
end     
def p2.laugh          #定义单例方法p2. laugh 
    puts "ha,ha,ha... "    
end   
 
p1.talk       # Hello! 
p2.talk       # Here is p2. 
p2.laugh      # ha,ha,ha... 

单例方法也叫作单件方法。定义单例方法,首先要生成一个实例对象,其次,
要在方法名前加上对象名和一个点号“.”。

---------------------------------------------------------------------------------------------------------
■访问级别-public protected private
   方法默认都是公有的( initialize 方法除外,它永远是私有的)。

-------------------------------------------------------------------------------------------------------
■关于模块
def method() #定义一个方法

puts  Math.sqrt(2)    # 1.4142135623731 #调用系统模块方法
puts  Math::PI       # 3.14159265358979  #调用系统模块常量

定义模块用 module...end 。模块与类非常相似,但是: 

 A)  模块不可以有实例对象;
 B)  模块不可以有子类。

---------------------------------------------------------------------------------------------------------
■关于命名空间
如果你觉得 Ruby 标准包里的 Math 模块提供的 sqrt 方法不好,不能够设置迭
代区间和精度,你重写了一个 sqrt方法。你的同事在他的程序里需要调用你的 sqrt
方法,也要调用标准 Math 模块提供的 sqrt 方法,怎么办呢?

模块的第二个作用:提供了一个命名空间(namespace),防止命名冲突。

看程序 E7.2-1.rb  : 

#E7.2-1.rb   
 
module  Me 
    def sqrt(num, rx=1, e=1e-10) 
    num*=1.0 
         (num - rx*rx).abs <e ?  rx :  sqrt(num, (num/rx + rx)/2, e)   
   end 
end 

module M3
  def M3.sqrt(num, rx=1, e=1e-10)   #单例方法
    num*=1.0 
         (num - rx*rx).abs <e ?  rx :  sqrt(num, (num/rx + rx)/2, e)   
   end 
end


include Math 
puts   sqrt(293)            # 17.1172427686237     


include M3
puts Math.sqrt(15)   #调用Math模块方法
puts M3.sqrt(293,5,0.01)  #调用M3的单例方法           
                                     
include Me                         
puts   sqrt(293)              # 17.1172427686237    
puts   sqrt(293, 5, 0.01)      # 17.1172429172153        

      
如你所见,只要 include模块名,就能使用不同模块的 sqrt方法。Me 模块被 include 在 Math 模块后面,Math 模块的 sqrt 方法就被
Me 模块的 sqrt 方法覆盖了。    

-----------------------------------------------------------------------------------------------------------------------------
■糅和(Mix-in) 与多重继承
糅和,也译作混合插入,也许就称作 Mix-in  比较合适。
现实生活中,一个乒乓球不仅是球类物体,也是有弹性的物体。 C++ 支持多重继承,多重继承有时会导致继承关系的混乱,Java 只提供了单继承,通过接口可以得到多重继承的优点,又没

有多重继承的缺点。Ruby  也是单继承,不是通过接口,而是通过 Mix-in  模块,来实现多重继承的优点

模块的第三个作用:实现了类似多重继承的功能。

 

class Student < Person 
  include Me   #将Me模块糅合进Student中
end 
 
aStudent=Student.new 
aStudent.talk              
puts aStudent.sqrt(20.7,3.3)   

 通过“ <  父类名 ”  ,一个子类可以得到父类的属性和方法;通过“ include 模块名 ”  ,一个子类可以得到某个模块的常量和方法。类不能被 include  。

 

 

aStudent=Student.new 
aStudent.extend(Me)     #将Me模块糅合进aStudent的实例
puts aStudent.sqrt(93.1, 25)    # 9.64883412646315 

 

include  方法为一个类的所有对象包含某个模块; extend  方法为一个类的某个对象包含某个模块。

------------------------------------------------------------------------------------------------------------------------------
■import---引入文件
require 包含文件,只加载一次,遇到同一文件时自动忽略;不同路径下的同
名文件会多次加载。 load 包含文件,加载多次,即使是相同路径下同一文件。
总结一下:
require,load用于包含文件;include,extend 则用于包含模块。
require 加载文件一次,load 加载文件多次。
require 加载文件时可以不加后缀名,load 加载文件时必须加后缀名。
require 一般情况下用于加载库文件,而 load 用于加载配置文件。

----------------------------------------------------------------------------------------------------------------------------------
■迭代器,代码块,闭包

从程序 E8.4-1.rb  可以看到调用一个块要用关键字 yield。每一次 yield,块就被调用一次。yield  还可以带参数调用块,看程序 E8.4-2.rb :

#E8.4-2.rb 
def  one_block 
    for num in 1..3 
    yield(num) 
  end 
end 
 
one_block  do |i| 
    puts "This is    block #{i}. "   
end 

 

运行结果:
This is    block 1.  
This is    block 2.  
This is    block 3.

一个简单的例子,但是你能发现其中的技巧:先写出方法的大致框架,调用方法的时候才告诉方法要作什么。

 

代码块是一段代码,相当于一个匿名方法,被调用它的方法所调用。如果我们不仅仅想调用代码块,还想把代码块作为参数传递给其它方法,就要使用闭包了。
闭包也是一段代码,一个代码块,而且能够共享其它方法的局部变量。
闭包既然是一段代码,也就有自己的状态,属性,作用范围,也就是一个可以通过变量引用的对象,我们称之为过程对象。一个过程对象用 proc 创建,用 call方法来调用。

def method(pr)   
  puts pr.call(7)    
end 
 
oneProc=proc{|k|  k *=3 } 
method(oneProc) 

 

4
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics