The basic knowledge about the Ruby

语句块

BEGIN{
    code
}

运行在程序开始

END{
    code
}

运行在程序结尾

注释块

=begin
    code
=end

也可以用#来做注释

文件和行的关键字

__FILE__ 是文件的关键字
__LINE__ 是行的关键字

数据类型

基本类型:Number、String、Ranges、Symbols

特殊值:true、false、nil

重要类型:Array和Hash

Number

可分为整型和浮点型,当出现下划线时,下划线可被忽略,如

a=1_000_000
puts a

结果为 1000000

String为字符串

在字符串中存在使用\的转移字符,同时在字符串中可以使用#{code}来插入ruby表达式的结果,如下:

puts "hello\nworld"
puts "Here is #{__LINE__}"

结果为:

hello
world
Here is 10

Ranges为范围

可以使用三种方式定义一个范围类型

(1..5)  结果为12345
(1...5)  结果为1234
Range.new 这个不清楚

Array数组

定义方式:

a=["hello", 12, "world"]

在我看来,ruby的数组是一种泛型的数组,不想c语言中,一个数组中的所有元素类型都是一样的,在ruby的数组中,可以有多种元素的类型。

在数组中可以调用方法length计算数组的长度

a.length

Hash哈希表

哈希表要知道键和值的概念,用键去找值,定义方式如下:

a={"red"=>123, "yellow"=>20, "white"=>89}

类和对象

五种变量类型(准确的说应该是五种变量的作用范围)

局部变量:    a, _a
实例变量:    @a
类变量:      @@a
全局变量:    $a
常量         VAR

注:常量必须以大写字母开头,常量只有在定义时能赋值(初始化),之后不允许修改其值,常量不能在方法中被定义,但可以在类中被定义(此时只被此类使用)

类的定义
clase Test
    code
end

定义一个名字为test的类

函数定义
def func
    code
end

定义一个名字为func的函数

注:

  • 使用#可以取变量的值,比如#a, #_a, #@a, #@@a, #$a

  • 类名的首字母一定要大写

  • 在 Ruby 中,类和方法也可以被当作常量。

运算符

ruby中的运算符和c中有很多相同的,在这里只列出与c用含义不同的运算符。

指数运算符, 103,结果为10的3次方

<=> 联合运算符,相当于字符串里面的strcmp函数,会有0,1,-1三种返回值

.eql? 如果接收器和参数具有相同的类型和相等的值,则返回 true。 1 == 1.0 返回 true,但是 1.eql?(1.0) 返回 false。

**= 例如:a**=3 等价于 a=a**3

..和… 这两个为范围运算符,(1..5)为1~5,(1…5)为1~4

:: 调用类中的常量值,同时也可以用于将类中的常量值升级到全局变量,如

情形一
class Test
    VAR = 10
end

puts Test::VAR   #显示为10
puts VAR  #报错

情形二
class Test
    ::VAR = 10
end

puts Test::VAR   #显示为10
puts VAR #显示为10

注:ruby中没有自增和自减运算符

判断(3类5种)

3类判断方式分别为:if, unless, case
5种判断方式分别为:if和if后缀模式,unless和unless后缀模式,case
先来说一下非后缀模式的3种,和c语言很像。

if
if condition
    code
elsif
    code
else
    code
end
unless
unless condition
    code
else
    code
end
case
case args
when a
    code
when b
    code
else
    code
end

注:

  • unless和case中没有elsif关键字,unless的条件为假时执行他的代码

  • if/elsif/unless/when的行尾可以添加then,但这不是必须的,then是可选关键字

2中后缀模式

code if condition  #condition为true时执行code
code unless condition  #condition为false时执行code

循环以及打断

循环3种,分别为:while,until和for

打断4种,分别为:break,next,redo,retry

while
while condition [do]
    code
end
until
until condition [do]
    code
end
for
for arg in expression [do]
    code
end

和判断一样,循环也拥有后缀模式

while后缀模式
code while condition

或者

begin
    code
end while condition

这面这种情况会先执行一次code再判断,相当于c语言中的do…while结构

until后缀模式
code until condition

或者

begin
    code
end until condition
break

同c语言中break语义一样

next

同c语言中continue语义一样

redo

重做,有点类似next,不同在于for循环中next会进入下一次循环,而redo还在此次循环中重新执行

retry

这个主要是和异常处理rescue关键字配合使用,当异常处理结束时可以使用retry重新执行之前的程序,具体详见后文。。。

方法

方法就是c语言中的函数,方法可以定义在类内,也可以定义在类外,类内的方法默认是public的属性,类外的方法默认是private的属性,如果想调用类内方法需要先实例化此类,或者使用如下方式定义此方法:

class Test
    def Test.func
        code
    end
end

Test.func

用类名.方法名的方式定义一个类内方法,可以直接在类外不需实例化就可被调用

别名

对方法可以定义一个别名,但只能在类外进行定义

alias foo  bar

其中bar是方法名,foo是新定义的别名

返回值

默认情况下,方法内的最后一条语句的值就是返回值,但也可以使用return进行返回,使用return可以返回多个值,比如

def func
    code
    return a,b,c
end

d=func

会将a,b,c三个值进行返回,返回值的接收者d会接收最后一个值c

可变数量参数

c语言中有可变数量的参数,ruby中也有

def func(*test)
    code
    len=test.length
end

func "a" "b" 2

这里的test就是一个可变数量的参数,他其实是一个数组

方法的首字母

方法的首字母一定要小写,不然会被解析器当作常量,导致出现问题

现在总结一下各个字母大小写的问题

类名首字母要大写

常量首字母要大写

变量首字母要小写

方法名首字母要小写

在ruby中,块是一个很重要的概念,他能让你更灵活的使用方法。

首先要记住一点,块最终会运行在同名的方法中。(BEGIN和END块除外)

下面是块的概念:

  • 块由大量的代码组成
  • 块需要一个名字
  • 块中的代码需要写在{}内
  • 块会在同名的方法中被运行
  • 可以在方法内通过yield来调用块

例如:

def func1
    puts "here is first line"
    yield 10   #块在此处被调用,参数为10
    puts "end line"
end

func1 {|n| puts "milld line #{n}"}  #方法func1在此处被调用,n为参数

块中的参数要用||包起来,里面可以放多个参数,并用逗号分割

除了使用yield外还可以使用call来调用一个块,例如

def func2(&arg)
    puts "start"
    arg.call(6,7)
    puts "end"
end

func2 {|n,m| puts "line #{n} and line #{m}"}

块中的内容作为参数被传入到了func2中,接收此内容的为arg,此参数必须为参数列别中的最后一个,并且有符号&作为修饰才能接收块的内容,然后参数arg调用方法call调用了块的内容,n和m为块的参数

方法的特殊参数;

  • *arg, arg成为一个数组,用于可变参数
  • &arg, 用于接收块的内容,并通过call方法对块内容进行调用

模块

在我看来,模块的最大用处是提供了命令空间,并能被外部的类引用(或叫插入),模块的定义方式和类很像

module Test
    code
end    

和类一样,模块名的首字母需要大写。在模块内部可以定义常量和方法(函数),与类中方法不一样的地方是,在模块中需要如下定义一个方法:

module Test
    def Test.func
        code
    end
end

a=Test.func

因为模块是不需要实例化的,所以只能如上定义一个模块方法(还记得如何定义一个不需实例化即可被调用的类方法吗)

引入文件

类似c语言中include引入某个文件,在ruby中使用require引入某个文件

require filename

此处需要注意的是引入文件的位置,我们可以如下指定一个位置

$LOAD_PATH << "."   #意思为当前目录下的文件

或者使用

require_relative file

来引入一个相对位置

注:一个文件可以包含多个模块

在类中引入模块

可以在类中引入某个模块,但前提是已经引入了此模块文件

include modulename

例如

$LOAD_PATH << "."

require "support.rb"

class User
    include Test

    def func
        Test::VAR  #使用Test模块中的VAR常量
    end
end
mixin机制

这个机制类似多重继承,但ruby不直接支持多重继承

module A
    def A.func1
        code
    end
end

module B
    def B.func2
        code
    end
end

class User
    include A
    include B
    def func3
        code
    end
end

a=User.new
a.func1
a.func2
a.cunf3

类User同时拥有了模块A和模块B的特性。

留言