• ruby 基础知识(一)


      突然今天发现一大神的博客:http://www.cnblogs.com/jackluo/archive/2013/01/22/2871655.html    相信初学者会受益颇多

    ruby  参考文档:http://www.tutorialspoint.com/ruby/

    关于ruby 的算法:http://liuzxc.github.io/blog/sorting-algorithm/

    变量类型

    描述

    示例

    局部变量(或伪变量)

    以小写字母或下划线卡头

    var    _var

    全局变量

    以$开头

    $var

    类变量

    类中定义,以@@开头

    @@var

    实例变量

    对象中定义,以@开头

    @var

    常量

    以大写字母开头

    Var

    一 ruby 中的关键字
     
     1.模块定义:module
     
     2.方法定义:def , undef
     
     3.检查类型:defined?
     
     4.循环语句:redo 重新开始循环,从这一次开始,retry 重头开始这个循环体,yield ,next 忽略本次循环的剩余部分,开始下一次的循环
     
     5.逻辑判断:not ,and ,or
     
     6.空值:true ,false , nil
     
     7.异常处理:rescue ,ensure
       Ruby中用begin/end …rescue…ensure … raise 来处理异常,retry可以用在rescue中。可以只用rescue或是ensure,两者都使用时,rescue必须在ensure前。
     
     8.对象引用:super ,self
     
     9.块的起始:begin/end
     
     10.文件相关:__FILE__ , __LINE__
     
     11.别名: alias
     
    二 ruby的数据类型
     
     1.数字,字符串,数组,哈希表,区间,正则表达式
     
     2.数组的每个元素可以是不同的类型:[ 2.4, 99,“thank you”,[ a, b ,c ] ,78 ]
     
     3.区间:1..5 表示1,2,3,4,5 
             1...5表示1,2,3,4 
     
    三 ruby 的赋值运算(#号后面的是结果)
     
     a = 1 ;b = 2 + 3 #a=1 ,b=5
     
     a ,b = b ,a      #a=5 ,b=1
     
     a = b = 1 + 2 + 3 #a=6 ,b=6
     
     a = (b = 1 + 2) + 3 #a=6 ,b=3
     
     x = 0 #x=0
     
     a,b,c = x, (x+1), (x+2) #a=0 ,b=1,c=2
     
    四 条件运算符
     
    <=>
    比较两个对象的大小,大于、等于、小于 分别返回1,0,-1
    "aab" <=> "acb" # -1 (第二个 a 的 ASCII 码小于 c)
     
    [5] <=> [4,9] # 1 (第一个元素 5 > 4)
     
     
    ===
    右边的对象是否在左边区间之内,返回 true, flase
    puts (0..9)=== 3.14 #true
    puts ('a'..'f')=== 'c' # true
     
     
     
    =~(匹配)
    用来比较是否符合一个正则表达式,返回模式在字符串中被匹配到的位置,否则返回 nil
     
     
    !~ (不匹配)
    断言不符合一个正则表达式,返回 true, flase
     
     
    <=            <     >        >=
    小于等于 小于 大于 大于等于
     
     
    五 条件判断语句
     
    1.  case when
     
    x=3
    case x
    when 1..2
     print "x=",x,";在 1..2中"
    when 4..9, 0
     print "x=",x,";在4..9,0中,或是0"
    else
     print "x=",x,";其它可能"
    end
     
    2. until
     
    a=1
    until a >=10
     print a," "
     a=a+1
    end
     
    3. while
     
    a=1
    while a <10
     print a," "
     a=a+1
    end
     
    一边是while a <10,一边是until a >=10,其它代码都一样,结果也一样
     
    4. for in 
     
       for i in 1..9
          print i," "
       end
     
     
    六 关键字
    times , upto , downto , each ,step
     
    3.times { print "Hi!" } #Hi!Hi!Hi!
     
    1.upto(9) {|i| print i if i<7 } #123456
     
    9.downto(1){|i| print i if i<7 } #654321
     
    (1..9).each {|i| print i if i<7} #123456
     
    0.step(11,3) {|i| print i } #0369
     
     
    七 对象
    1. 属性的简写
     
    attr_writer :motherland 相当于
    def motherland=(value)
    return @motherland =value
    end
     
    attr_ reader :motherland 相当于
    def motherland
    return @motherland
    end
     
    attr_accessor :motherland 相当于attr_reader:motherland; attr_writer :motherland
     
    八  代码书写规范
     
    a=5
    b=3
    puts a>b ? "a>b" : "a<=b" # a>b
    puts (a>b)? ("a>b") : ("a<=b") # a>b
    #puts a>b? "a>b" : "a<=b" 错误语句
     
    九 面向对象(重写 重载)
     
     1.Ruby语言,只有重写,没有其它语言具有的严格意义上的重载
     
     2.Ruby还支持可变参数,我们看程序 E6.1-2.rb :
     
    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
       
    十 实例变量、类变量、类方法
     
    class StudentClass
    @@count=0
    def initialize
    @@count+=1
    end
    def StudentClass.student_count
    puts "This class have #@@count students."
    end
    end
     
    p1=StudentClass.new
    p2=StudentClass.new
    StudentClass.student_count # This class have 2 students.
    p3=StudentClass.new
    p4=StudentClass.new
    StudentClass.student_count # This class have 2 students.
     
     
    十一 单例方法
     
    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...
     
    单例方法也叫作单件方法。定义单例方法,首先要生成一个实例对象,其次,要在方法名前加上对象名和一个点号“.”
     
    十二 模块
     
    Math 模块提供了许多方法,比如:求平方根 sqrt ,使用的时候要这么写:模块名.方法名(参数)
    你可以 Math.sqrt(37.2/3) ,Math.sqrt( a*5+b ) 
     
    Math 模块还提供了两个常量,圆周率π 和自然对数底 e,使用的时候要这么写:模块名::常量名。
     
    定义模块用module...end 。模块与类非常相似,但是:
    A) 模块不可以有实例对象;
    B) 模块不可以有子类。
     
    十三 糅和(Mix-in) 与多重继承
     
    1.我们有一个Student类,有着Person类的属性和方法,还会做数学题——求平方根。已经有了Me模块,只要Mix-in 在Student类里就可以了。
    看程序 
    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
     
    class Person
     def talk
      puts "I'm talking."
     end
    end
     
    class Student < Person
      include Me
    end
     
    aStudent=Student.new
    aStudent.talk # I'm talking.
    puts aStudent.sqrt(20.7,3.3) # 4.54972526643248
     
    2.include 方法相对应的,还有一个 extend 方法。如果并不是Student类的每个对象都会求平方根,只有某一个学生会,如何办到呢?
     
    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
     
    class Student
    end
     
    aStudent=Student.new
    aStudent.extend(Me)
    puts aStudent.sqrt(93.1, 25) # 9.64883412646315
     
    十四 load  require
     
    require,load用于包含文件;include,extend则用于包含模块。
     
    require加载文件一次,load加载文件多次。
     
    require加载文件时可以不加后缀名,load加载文件时必须加后缀名。
     
    require一般情况下用于加载库文件,而load用于加载配置文件。
     
    利用load 多次加载文件的特性,可以用来实现程序的无缝升级和系统的热部署。程序功能改变了,你只需要重新load 一次,其它代码与它再次交互的时候,这个程序实际上已经不是原来的程序了
     
    十五   字符串详解
     
    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
    运行结果:
    this is str3
    this is str4
     
    Here is string document, str5
    line one;
    line two;
    line three.
    OK
     
    1.%q 用来生成单引号字符串;%Q用来生成双引号字符串。%q或者%Q后面跟着的是分隔符,可以是配对的! !; / /; < >; ( ); [ ] ;{ };等等
     
    2.str5是一个字符串文档,从 <<文档结束符的下一行开始,直到遇到一个放置在行首的文档结束符,结束整个字符串文档。
     
    3.一个数组可以用join 方法转换成字符串,join( ) 内的参数也是一个字符串,用来分隔数组的每个元素,例如:arr.join(", ")
     
    4.字符串操作
     
    (1)
    str = ' this' + " is"
    str += " you"
    str << " string" << " ."
     
    puts str*2   # this is you string . this is you string .
     
     
    str = " this is you string ."
    puts str  #    this is you string .
     (2) 字符串内嵌表达式
     
    Ruby表达式在 #{ } 之中,这些表达式在使用这个字符串的时候被计算出值,然后放入字符串
     
    def hello(name)
        " Welcome, #{name} !"
    end
     
    puts hello("kaichuan") # Welcome, kaichuan !
    puts hello("Ben") # Welcome, Ben !
    十六 正则表达式
     
    1.Ruby中,可以使用构造器显式地创建一个正则表达式,也可以使用字面值形式 /正则模式/ 来创建一个正则表达式
     
    str="Hello,kaichuan,Welcome!"
    puts str =~ /kaichuan/ #6
    puts str =~ /a/ #7
    puts str =~ /ABC/ #nil
     
    在字符串str中找我的名字 kaichuan。找到了,在字符串str的第6个字符处。和数组一样,字符串的起始索引位置是0。
     
    2.不匹配一个正则表达式,用“!~” ,不能用“!=”。 “!~”用来断言不符合一个正则表达式,返回 true,flase
     
    str="Hello,kaichuan,Welcome!"
    puts str !~ /kaichuan/ # false
    puts str !~ /a/ # false
    puts str !~ /ABC/ # true
     
    3.将文章中所有的windows2000 或者 windows98 换成 Windows XP,不论单词开头大小写,但是不带数字的windows不换;并且要把2006年12月31日改成当前时间
     
    strdoc=<<DOC_EOF
    This is windows2000 or windows98 system.
    Windows system is BEST?
    Windows2000 running in 12-31-2006,……
    DOC_EOF
     
    re = /[w|W]indows(?:98|2000) /
    strdoc.gsub!(re, "Windows XP ")
    re = /[1-9][0-9]-[1-9][0-9]-dddd/
    time = Time.now.strftime("%m-%d-%Y")
    strdoc.gsub!(re, time)
    puts strdoc
    strdoc.gsub!(re, "Windows XP "),是把字符串strdoc里所有匹配正则模式re的子串替换为 "Windows XP "。 gsub!是替换所有子串
     
    strdoc.gsub!(re, time),是把字符串strdoc里所有匹配正则模式re的子串替换为字符串time。
     
    time = Time.now.strftime("%m-%d-%Y"),取出系统当前时间,并且格式化成( 月-日-年 )的形式,生成一个字符串time。
     
    十七 迭代器、代码块、闭包
     
    1. 
    (1..9).each {|i| print i if i<7}
    迭代器each 是数组类的一个方法;大括号{ }里的代码是代码块,简称块。你可以用大括号{ }将代码组织成块,也可以用 do…end将代码组织成块。大括号{ }的优先级高于do…end
     
    2.调用一个块要用关键字yield。每一次 yield,块就被调用一次
    def one_block
        yield
        yield
        yield
    end
     
    one_block { puts "This is a block. " }
     
    运行结果:
    This is a block.
    This is a block.
    This is a block.
     
    3.一个块可以接收yield 传来的参数,还可以将结果返回给调用它的方法
    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.
    4.第一次do_something遇到yield,调用了代码块{ 输出1..9中小于5的数 } ;在程序的另一处do_something的时候,我们希望做一些不同的事,所以我们写了一个不同于前一次的代码块{ 输出3次“Hi!”}。
       这是一个简单的例子,但是你能发现其中的技巧:先写出方法的大致框架,调用方法的时候才告诉方法要作什么
     
    def do_something
    yield
    end
    do_something do
    (1..9).each {|i| print i if i<5}
    puts
    end
     
    do_something do
    3.times { print "Hi!" }
    puts
    end
     
    5.代码块是一段代码,相当于一个匿名方法,被调用它的方法所调用
    class Array
        def one_by_one
            for i in 0...size
                yield(self[i] )
            end
        puts
     end
    end
     
    arr = [1,3,5,7,9]
    arr.one_by_one {|k| print k , ", "} # 1, 3, 5, 7, 9,
    arr.one_by_one {|h| print h*h, ", "} # 1, 9, 25, 49, 81,
    6.闭包也是一段代码,一个代码块,而且能够共享其它方法的局部变量
     
     
    def method(pr)
    puts pr.call(7)
    end
    oneProc=proc{|k| k *=3 }
    method(oneProc)
    运行结果:
    >ruby E8.4-4.rb
    21
    >Exit code: 0
    再看一个闭包共享其它方法局部变量的例子;
    def method(n)
    return proc{|i| n +=i }
    end
    oneProc=method(3)
    puts oneProc.call(9) #12
    puts oneProc.call(5) #17
    方法method 返回一个Proc对象,这个对象引用了这个函数的参数:n 。即使 n这个参数在闭包被调用时已经不在自己的作用域里了,这个闭包还是可以访问 n这个参数,并且和方法method 共同拥有变量 n 。开始的时候,方法method 的变量 n是3;oneProc.call(9)的时候,oneProc更新了变量 n,把n=12传回给方法method;oneProc.call(5)的时候,oneProc取出方法method的变量 n=12,更新为n=17,传回给方法method的同时,也把n=17作为自己的返回值输出。
     
     
     
     
  • 相关阅读:
    DShow实现一个avi视频的播放(含有个人解释和注释)
    指针和引用的区别
    从头看算法导论 习题2.3-7 深入分析
    程序员福利各大平台免费接口,非常适用
    NYOJ 58 最少步数
    NYOJ 42 一笔画问题
    NYOJ 1058 部分和问题
    NYOJ 21 三个水杯
    winform里面网页显示指定内容
    C#中List<T>对象的深度拷贝问题
  • 原文地址:https://www.cnblogs.com/keno32/p/5133065.html
Copyright © 2020-2023  润新知