专注收集记录技术开发学习笔记、技术难点、解决方案
网站信息搜索 >> 请输入关键词:
您当前的位置: 首页 > Ruby/Rails

ruby学习札记

发布时间:2011-06-29 18:27:10 文章来源:www.iduyao.cn 采编人员:星星草
ruby学习笔记

数组
    建立数组
        要制作新的数组,可以使用逗号分割元素,并以"[]"框住所有数据。
  name = ['a', 'b', 'c', 'd']
  当数组对象的内容尚未确定时,可以只写"[]",这表示空的数组对象。
  name = []
 从数组中取得对象
     要获取数组特定位置的对象,可以写:数组名[索引]
  name[0]
  数组的索引是从0开始的。
 将对象存进数组
     数组名[索引]=想要存放的对象
  name[0]='d'
 数组的内容
  数组里可以存放任何对象。
 数组的大小
  可以使用size方法:array.size。
  p name.size
 逐项处理数组内容
  数组.each {|变量|
      想要反复执行的动作
  }
  name.each{|n|
     print n, "\n"
  }

HASH
 建立hash
     建立hash时使用"{}",使用"=>"符号定义用来取出对象的键与该键取出的值。
  font_table = {"normal" => "+0", "small" => "-1", "big" => "+1"}
 从hash获取对象
  hash名[键]
  要将对象存进hash则写成:hash[键]=想要存放的对象
  例如:
  p font_table["small"]
  p font_table["normal"]
  p font_table["big"]
  font_table["verybig"] = "+2"
  p font_table["verybig"]
  注意:hash没有固定的顺序,并不能按存方式的顺序取出数据。
 逐项处理hash内容
  hash.each{|键的变量, 值的变量|
     想要反复执行的动作
  }

正则表达式
    建立正则表达式对象的语法:/样式/
 拿正则表达式匹配字符串时,写成:/样式/=~想要匹配的字符串
 当匹配成功时会反悔匹配成功的位置。文字的位置是从0开始的。匹配失败时则会反悔nil。
 正则表达式右侧的"/"后面如果加上一个"i",则匹配是就不区分大小写了。
 例如:
 p /Ruby/ =~ "ruby"
 p /Ruby/i =~ "ruby"

从命令行输入的数据
    要取得命令行所传入的数据,可以使用"ARGV"这个数组对象。
 在ARGV数组中,以字符串形式存放着在命令行对指令脚本传入的实参。
 利用命令行给指令脚本指定参数的场合,在参数之间需要用空格隔开进行输入。
 将字符串转换成数值,必须使用to_i方法。

读取文件
    读入文件内的文本数据并显示
     read_text.rb
  filename = ARGV[0]
  file = open(filename)
  text = file.read
  print text
  file.close
 从文件逐行读入数据并显示出来
     gets_text.rb
  filename = ARGV[0]
  file = open(filename)
  while text = file.gets do
     print text
  end
  file.close
 只显示文件里符合特定样式的几行
     simple_grep.rb
  pattern = Regexp.new(ARGV[0])
  filename = ARGV[1]
  file = open(filename)
  while text = file.gets do
     if pattern =~ text
        print text
     end
  end
  file.close

变量
    一个变量属于哪一种变量则是由变量名称决定的。
 1、局部变量:变量名以小写字母或"_"起始的变量。
 2、全局变量:变量名以"$"起始的变量。
 3、实例变量:变量名以"@"起始的变量。
 4、类变量:变量名以"@@"起始的变量。
 5、虚拟变量:"true"、"false"、"self"等特定名称的变量。

常数
 常数名称必须以大写字母开始。

对象的同一性
 所有的对象都被赋予身份标识。对象的身份标识(ID)可以通过object_id方法获得。
 "=="和"eql?"判断是否同值。在同样的使用场合下,两者的动作情况是一样的。
 在施行"=="时,需要进行必要的变换,eql?可以不需要变换就能进行比较。
 在一般的程序中,使用"=="的场合比较普遍。hash内部的键与给定的键进行比较等情况,在需要严格地进行比较的场合下,使用eql?来比较。

条件判断
 条件判断语句大致有下面3种:
 1、if语句
    语法:
    if 条件1 then
       语句1
    elsif 条件2 then
       语句2
    elsif 条件3 then
       语句3
    else
       语句4
    end
    then可以省略。
 2、unless语句
    unless语句则是与if完全相反的语句。
    语法:
    unless 条件 then
       语句1
    else
       语句2
    end
    then可以省略。
    等价如下if语句:
    if 条件
       语句2
    else
       语句1
    end
 3、case语句
    语法:
    case 想要比较的对象
    when 值1 then
       语句1
    when 值2 then
       语句2
    when 值3 then
       语句3
    else
       语句4
    end
    then可以省略。

 if与unless也可以写在想要执行的语句后面。
 print "a比b大" if a > b
 等价下面语句
 if a > b
    print "a比b大"
 end
 
 "==="与case表达
    在case表达式中,判断与when后指定的值是否一致可以使用"==="运算符来表示。
    "==="的左边如果是数值或字符串则意义与"=="是一样的。在正则表达式的场合下
    相当于"=~",即匹配判定。在类的场合下,判断"==="右边的对象是否是类的实例。
    与其说"==="是进行其左右两边"值"的比较,还不如把它看作判断是否等同。
    case value
    when A                if A === value
       处理1                 处理1
    when B                elseif B === value
       处理2                 处理2
    else                  else
          处理3                 处理3
    end                   end

循环
 1、times方法
    语法:
    想要重复的次数.times do
       想要重复执行的动作
    end
    想要重复的次数.times {
       想要重复执行的动作
    }
    使用times方法时,在语句块中也可以知道现在是循环到第几次了。
    想要重复的次数.times { |变量|
       想要重复执行的动作
    }
    例子:
    from = 10
    to = 20
    sum = 0
    (to - from + 1).times{ |i|
       sum = sum + (i + from)
    }
    print sum, "\n"
 2、for语句
    for 变量 in 开始的数值 .. 结束的数值 do
        想要重复执行的动作
    end
    for 变量 in 对象 do
        想要重复执行的动作
    end
    do可以省略。
    ".."与"..."只是一种用来建立范围对象的记号而已。
    for语句与times方法不同,可以自由更改初始值与终止值。
    例一:
    from = 10
    to = 20
    sum = 0
    for i in from .. to
        sum = sum + i
    end
    print sum, "\n"
   
    例二:for_names.rb
    names = ["awk", "Perl", "Python", "Ruby"]
    for name in names
        print name, "\n"
    end
 3、while语句
    语法:
    while 条件 do
       想要重复执行的动作
    end
    do可以省略。
 4、until语句
    until 条件 do
       想要重复执行的动作
    end
    do可以省略。
 5、each变量
    对象.each do |变量|
       想要重复执行的动作
    end
    对象.each { |变量|
       想要重复执行的动作
    }
    do可以省略。
 6、loop方法
    没有结束条件,只是不断进行循环处理的方法。
    例子:
    loop {
       print "Ruby"
    }
 用来控制循环的命令
 命令     用途
 break    停止动作,马上跳出循环
 next     直接跳到下一次循环
 redo     以相同的条件重新进行这一次循环
 例子:
 break_next_redo.rb
 print "break的示例:\n"
 i = 0
 ["Perl", "Python", "Ruby", "Scheme"].each{ |lang|
    i += 1
    if i == 3
       break
    end
    p [i, lang]
 }
 
 print "\nnext的示例:\n"
 i = 0
 ["Perl", "Python", "Ruby", "Scheme"].each{ |lang|
    i += 1
    if i == 3
       next
    end
    p [i, lang]
 }
 
 print "\nredo的示例:\n"
 i = 0
 ["Perl", "Python", "Ruby", "Scheme"].each{ |lang|
    i += 1
    if i == 3
       redo
    end
    p [i, lang]
 }

方法
 调用方法
     语法:
  对象.方法名(实参1, 实参2, ..., 实参n)
 方法的分类
     a、实例方法:当对象(实例)存在时,把该对象作为接收者的方法,叫做实例方法。
  b、类方法:当接收者不是对象而是类时,这个方法称为类方法。
     调用类方法时,"."也可以写成"::"
  c、函数性的方法:没有接收者的方法,称为函数性的方法。
 定义方法
     语法:
  def 方法名(参数1, 参数2, ...)
     想要执行的动作
  end
  可以为参数指定预设值。预设值是没指定实参时使用的值,写成"参数名 = 值"的形式。
  当方法不止一个参数时,预设值必须从右端的参数开始指定。
  例子:
  hello_with_default.rb
  def hello(name="Ruby")
      print("Hello, ", name, ".\n")
  end
  hello()
  hello("Newbie")
  在方法中使用return语句可以指定返回值:return 值
  return语句可以省略,这时方法中最后一个语句的计算值会是返回值。
  def area(x, y, z)
      xy = x * y
   yz = y * z
   zx = z * x
   (xy + yz + zx) * 2
  end
  p area(2, 3, 4)
  p area(10, 20, 30)
  方法的返回值不一定是最后一行,如下:
  def max(a, b)
     if a > b
        a
     else
        b
     end
  end

类与模块
    类与实例
     要建立新的对象,必须使用每个类的new方法。
  想知道对象属于哪个类,可以使用class方法。
  要判断一个对象是否是某个类的实例,可以使用instance_of?方法。
  Ruby语言所有的类都是Object类的子类(Object是唯一没有父类的类)。
  is_a?方法可以用来检查实例是否属于某个类,还可以检查有继承关系的父类。
  instance_of?方法与is_a?方法都定义在Object类里,所以所有对象都可以使用这些方法。
 自己定义类
     class语句
      语法:
   class 类名
       类定义
   end
   类名一定要以大写字母开始。
  initialize方法
      调用new方法建立对象时,这个initialize方法会被调用;同时,传递给new的所有实参都会传递给initialize方法。
  定义访问方法
      定义                意义
      attr_reader:name    只定义用来读取的方法(定义name方法)
      attr_writer:name    只定义用来写入的方法(定义name=方法)
      attr_accessor:name  定义用来读取与写入的方法(定义上述两个方法)
      用来设定实例变量的方法称为setter,而用来读取实例变量的方法称为getter。这两种方法放在一起,合称为访问方法(accessors)。
  类方法
      类方法有3种定义的方式:
   a、写成"def 类名.方法名~end"
      class HelloWorld
         def HelloWorld.hello(name)
          print name, " said Hello."
      end
      end
      HelloWorld.hello("John")
   b、写成"class<< 类名~def 方法名~end end"
      class HelloWorld
         .
      .
      end
      class << HelloWorld
         def hello(name)
          print name, " said Hello."
      end
      end
      HelloWorld.hello("John")
   c、写成"class 类名~def self.方法名~end end"
      class HelloWorld
         def self.hello(name)
          print name, " said Hello."
      end
      end
      HelloWorld.hello("John")
   方法的表示法:类.方法或类::方法
  常数
      类内的常数可以使用"::"连接类与常数名称,从类外部访问。
   class HelloWorld
      Version = "1.0"
   end
   p HelloWorld::Version
  类变量
      以"@@"开始的变量称为类变量。类变量是该类所有实例共用的变量。
   例子:
   hello_count.rb
   class HelloCount
      @@count = 0
      def HelloCount.count
          @@count
      end
      def initialize(myname="Ruby")
          @name = myname
      end
      def hello
          @@count += 1
       print "Hello, world. I am ", @name, ".\n"
      end
   end
   bob = HelloCount.new("Bob")
   alice = HelloCount.new("Alice")
   ruby = HelloCount.new
   p HelloCount.count
   bob.hello
   alice.hello
   ruby.hello
   p HelloCount.count
  扩充类
      还可以在已经定义的类中新增方法。
   例子:
   ext_string.rb
   class String
       def count_word
        ary = self.split(/\s+/)
     return ary.size
    end
   end
   str = "Just Another Ruby Newbie"
   p str.count_word
  使用继承
      语法:
   class 类名 < 父类名
       类定义
   end
  限制方法的调用
      Ruby提供了3中限制层级:
   a、public---将方法公开为外部可以使用的实例方法。
   b、private---将方法限制为只有内部可以使用(不允许接在接收者后面调用)
   c、protected---将方法限制为只有内部可以使用。
   例子:
   acc_text.rb
   class AccTest
       def pub
           puts "pub is a public method."
       end
    public :pub
    def priv
        puts "priv is a private method."
    end
    private :priv
   end
   acc = AccTest.new
   acc.pub
   acc.priv
   或
   class AccTest
       public
    def pub
           puts "pub is a public method."
       end
    
    private
    def priv
        puts "priv is a private method."
    end
   end
   acc = AccTest.new
   acc.pub
   acc.priv
 什么是面向对象
     面向对象的特征:封装、多态
 什么是模块
     模块的用法
  1、提供命名空间
     命名空间(namespace)是为了让方法、常数、类名称不互相冲突而设计的机制。
     以模块形式提供的方法必须使用"模块名.方法名"的方式调用。以这种形式调用的方法又称为模块函数。
     当模块内部定义的方法及常数的名称没有与现在命名空间冲突时,省略模块名称会比较方便。使用include可以将模块所拥有的方法名称与常数名称读入现在的命名空间里。
  2、以Mix-in方式提供功能
     将模块混进类里,称为"Mix-in"。在类的定义内使用include,可以将模块里所定义的方法和常数纳入类定义里。
     例如:
     module MyModule
        #想要共同提供的方法等
     end
     class MyClass1
        include MyModule
     #MyClass1所特有的方法
     end
     class MyClass2
        include MyModule
     #MyClass2所特有的方法
     end
 自己定义模块
     语法:
  module 模块名
    模块定义
  end
  常数
      与类一样,模块内部定义的常数可以直接连接在模块名称后面引用。
  定义方法
      与类一样,module内部也可以定义方法。只是方法在定义以后,只能在模块内部调用,不能使用"模块名.方法名"的调用方式。要将方法对模块外部公开,必须使用module_function。module_function的实参是想要公开的方法名称的符号。

错误处理与例外
    错误消息格式:
     文件名:行号:in '方法名':错误消息(例外类)
       from 调用方法的位置
     .
     .
 例外处理的写法
     begin
     有可能发生例外的处理动作
  rescue
     例外发生时的处理措施
  end
  Ruby将例外也视为对象。在rescue后面指定变量名称,可得例外对象。
  begin
     有可能发生例外的处理动作
  rescue => 用来存放例外对象的变量
     例外发生时的处理措施
  end
 例外发生时会自动设置的变量
     变量     意义
  $!       最后发生的例外(例外对象)
  $@       最后例外所发生的位置相关信息
 例外对象的方法
     方法名     意义
  class      例外类别
  message    例外的消息
  backtrace  例外的发生位置信息($@等同于$!.backtrace)
 善后处理
     如果有些动作无论是否发生例外都想要确实完成,则写在ensure语句块里。
  begin
     有可能发生例外的处理动作
  rescue => 用来存放例外对象的变量
     例外发生时的处理措施
  ensure
     无论例外发生与否都坚持要执行的动作
  end
 重新执行
     在resure语句块里可以使用retry语句重新执行begin语句块的动作。
  例如:
  file = ARGV[0]
  begin
    io = open(file)
  rescue
    sleep 10
    retry
  end
 rescue修饰符
     格式:运算式1 rescue 运算式2
  例子:n = Integer(val) rescue 0
 例外处理语法的补充
     def foo              def foo
    begin                方法内容
      方法内容         rescue => ex
    rescue => ex         例外处理
      例外处理         ensure
    ensure               后置处理
      后置处理         end
    end
  end
  一样的,在类定义里也可以写rescue与ensure语句块。但是在类定义发生例外时,例外发生位置之后的所有方法定义会被跳过,所以一般的程序不会这样用。
  class Foo            class Foo
    begin                类定义内容
      类定义内容         rescue => ex
    rescue => ex           例外处理
      例外处理           ensure
    ensure                 后置处理
      后置处理         end
    end
  end
 指定要捕捉的例外
     当不止一种例外可能发生,而想要分开处理这些例外时,可以使用多个rescue语句块来处理。
  begin
    有可能发生例外的处理动作
  rescue Exception1, Exception2 => 变量
    Exception1或Exception2例外的处理措施
  rescue Exception3 => 变量
    Exception3例外的处理措施
  rescue => 变量
    其他例外的处理措施
  end
  指定类名称,就可以捕捉预想的例外。
  file1 = ARGV[0]
  file2 = ARGV[0]
  io = nil
  begin
    io = open(file1)
  rescue Errno::ENOENT, Errno::EACCES
    io = open(file2)
  end
     Errno::ENOENT与Errno::EACCES是文件不存在时与没有文件打开权限时会发生的例外。
 例外类
     rescue语句块所指定的例外种类,是例外的类名称。
  在rescue语句块没有指定例外类时,会捕捉StandardError与其子类。
  要定义各种例外类时,一般会先继承StandardError类,接着再往下继承各种例外类。
  class MyError < StandardError; end
  class MyError1 < MyError; end
  class MyError2 < MyError; end
  class MyError3 < MyError; end
  这样定义的话,只要像下面这样写,就可以捕捉到MyError1、MyError2与MyError3。
  begin
    .
    .
  rescue MyError
    .
    .
  end
 引发例外
     想要让例外发生时则使用raise方法。这个方法用在想要在某些条件下主动产生出新的例外或者再次引发之前捕捉到的例外,将例外交给调用来源时。
  raise有下面4种形式:
  1、raise 消息
     引发RuntimeError例外。指定的字符串会被当做新的例外对象的消息。
  2、raise 例外类
     引发指定的例外。
  3、raise 例外类,消息
     引发指定的例外,并且指定的字符串会当做新的例外对象的消息。
  4、raise
     写在rescue语句块外部则引发RuntimeError例外;写在rescue语句块内则可以自动再次引发最后发生的例外($!)。
 catch与throw
     在catch的实参中指定符号,连同语句块一起调用,那么在这个语句块内若以相同符号作为实参调用throw方法则语句块会在这里中断执行。
  例子:
  catch(:exit) {
    loop {
      loop {
     :
     if val != 0         #在某个条件成立时
       throw :exit, val  #抛出:exit跳离catch
     end
   }
    }
  }
  指定throw的第2个实参时,这会称为catch的返回值。

数值类
 

友情提示:
信息收集于互联网,如果您发现错误或造成侵权,请及时通知本站更正或删除,具体联系方式见页面底部联系我们,谢谢。

其他相似内容:

热门推荐: