• ruby


    1。交互方式运行ruby输入ruby后直接写代码,最后按Ctrl+D代表结束;另外可以用irb(Interactive Ruby)来执行交互编程。运行本地的ruby程序分两步,一用irb load进xxx.rb,二然后运行这个文件中的方法。

    2。ri是一种本地命令行工具,用来浏览RDoc文档。

    3。方法是通过向对象发送消息唤起调用的,消息中包含方法名和方法可能需要的参数。

    4。ruby中得到数字绝对值方法:-123.abs既可,但java和其它语言中则是传给其它函数如:Math.abs(-123);这说明ruby是面象对象的。

    5。ruby方法定义和调用是可以不加(),但为了可读和优先级,最好加上()。表达示内插#{name}。

    6。全局变量:$xxx;类变量@@xxx;实例变量:@xxx。局部变量、方法参数、方法名必须以小写字母或下画线开始;类名称、模块名称和常量都必须以一个大写字母开始。方法名可以?!=结尾。

    7。ruby数组和散列表都用来存储对象,只是所用的键不一样。

    8。nil是一个对象,不像别的语言中的null,是只这个对象表示什么也没有的对象。

    9。使用语句修饰符相当于把if/while的条件和执行语句益交换了。

    10。block是与方法调用放一起的,入在方法调用最后,类似传入方法的参数,可以实现回调。使用yield语句实现回调。yield(xxx,xxx)支持传参数,在block中使用|xxx,xxx|引用参数。例:5.times { puts "a"}

    11。ruby中会有许多内置的变量,如$_ 。

    12。ruby的构造器为initialize。

    13。ruby中已定义的类可以随时修改,并且修改可以反应当已经实例化的对象中?

    14。类和子类定义:class Parent [code] end  class Sub < Parent [code] end。super关键字用来调用父类中的同名方法。并且ruby中大部分方法都有返回值,因为一个方法的最后一后默认前面加了一个return。def name @name end相当于getXXX,简化方法为attr_reader :name, :age这种方式创类似的建getXXX方法。并且会自动创建冒号后面的变量。def name=(n) @name = n end,既定义一个等号结尾的方法名,能使其出现在赋值操作左侧。简洁方法:attr_writer :name。虚拟方法的概念:就是实例方法名和调用时所用的方法名不同。

    15。类变量@@开头,并且必须实用前要实例化。类方法定义方法为类名加点号加方法名,如Song.classMethod。

    16。ruby方法访问权限有三种:public,protected和private。方法默认是public的(initialize方法除外,默认为private的);private的方法接收者只能是self。ruby的访问控制是在运行期间确实而非静态判定。

    17。变量不是对象,默认的是局部变量。对象复制person.dup,对象冻结person.freeze 。

    18。数组用法有a[1,3],a[1...3] = [xxx]等,中间部分自动添nil。

    19。执行block传参数时,如果将方法中(不仅仅是方法,还可以是周围的其它环境)的变量传入block块,block操作结果对其产生影响到。block最后一条表达式的值将作为返回值返回给调用的方法。block可做事务处理,也可被用作闭包。

    20。迭代方法有each,find,inject,collect。ruby中为内部迭代器,java中为外部迭代器,其实,迭代器本质上是迭代器模式,有内外之分。

    21。method(*args) 中*args为可变数组。定义方法时加def method(&action) action.call(self) end则方法调用时会寻找block,也就是说这个方法要和block块配合使用。

    22。字符串可以%q,%Q分隔符来实现,还可以用here documents实现。

    23。ruby用区间实现序列、条件和间隔。..代表闭合区间,...代表左闭右开区间。区间在内存中被表示为Range对象而不是所有的list,可以用to_a转为list。<=>比较符根据大小返回-1,0,1。succ方法指向区间的下个对象,一个类实现了succ方法和<=>就可以做为区间。区间可以做为条件。区间可以做为间隔,判断一些值是否落入区间内。如(1..10) === 5。

    24。查询用的方法通常以?结尾,赋值的用=结尾,危险的方法用!结尾。定义方法时*号表示可变参数;调用方法时*号表示数组展开。方法&表示关联的block会转化为Proc对象作为方法的参数。方法总会返回最后一个表达式的值。

    25。ruby并行赋值a,b = 2,3。方法返回多个值不会出错,是以数组形式返回。如:return n,m。

    安装

    yum install ruby
    yum install ruby-irb
    • 1
    • 2

    然后ruby -v可以查看Ruby版本,直接irb就可以进入irb了,它是Ruby的交互式解释器。

    使用irb

    ‘=>’后面给出的是返回值。

    [lzh@hostlzh /]$ irb
    irb(main):001:0> a=3
    => 3
    irb(main):002:0> b=2.13
    => 2.13
    irb(main):003:0> a**b
    => 10.3816951625648
    irb(main):004:0> exit
    [lzh@hostlzh /]$
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    Ruby脚本

    ruby的脚本文件后缀名是.rb。

    [lzh@hostlzh /]$ cd /home/lzh/文档/Ruby/
    [lzh@hostlzh Ruby]$ touch 1.rb
    [lzh@hostlzh Ruby]$ gedit 1.rb
    • 1
    • 2
    • 3

    第一行还是要指明解释器在哪,看一下:

    [lzh@hostlzh /]$ which ruby
    /usr/bin/ruby
    • 1
    • 2

    书写.rb脚本文件:

    #!/usr/bin/ruby
    print("your name? ")
    name=gets()
    puts("Hello,#{name},emmm")
    puts("Bye,#{name},6666")
    • 1
    • 2
    • 3
    • 4
    • 5

    用解释器执行:

    [lzh@hostlzh Ruby]$ ruby 1.rb
    your name? lzh
    Hello,lzh
    ,emmm
    Bye,lzh
    ,6666
    [lzh@hostlzh Ruby]$
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    可以看到print是不换行的,puts是换行的。但是gets()方法会把换行符一起读进来!所以#{name}取name的值输出出来是带换行的。


    Ruby语法极其自由,如写成:

    #!/usr/bin/ruby
    print "your name? "
    name=gets
    puts "Hello,#{name},emmm"
    puts "Bye,#{name},6666"
    • 1
    • 2
    • 3
    • 4
    • 5

    也一样跑:

    [lzh@hostlzh Ruby]$ ruby 1.rb
    your name? SB
    Hello,SB
    ,emmm
    Bye,SB
    ,6666
    [lzh@hostlzh Ruby]$
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    (函数在不需要参数而且没有歧义时括号可以不要)

    但是为了减少学习Ruby和学习Python3的成本,我还是都打上的好吧。

    Python的哲学就是”做一件事只有一种方法”,而Ruby与之完全相反,推崇用多种方法来解决问题,这也导致了Ruby工程难以多人共同协作。

    Ruby是纯粹的面向对象,这是吸引我学习Ruby的一个重要方面(体会一下其它语言中存在的问题),还有想试试Ruby的语法糖。

    命令行输入

    脚本的一大特性就是应当能直接接受来自命令行的输入,命令行的输入按顺序称为变量ARGV[i],可以像使用其它变量那样使用它。

    #!/usr/bin/ruby
    puts("第一个参数=#{ARGV[0]},第二个参数=#{ARGV[1]}")
    • 1
    • 2
    [lzh@hostlzh Ruby]$ ruby 1.rb lzh sb
    第一个参数=lzh,第二个参数=sb
    [lzh@hostlzh Ruby]$
    • 1
    • 2
    • 3

    标准输入输出

    标准输入在键盘,标准输出在显示器。

    标准输入

    gets实际上是STDIN的gets()方法:

    #!/usr/bin/ruby
    name=STDIN.gets()
    puts("Hello,#{name},SB")
    • 1
    • 2
    • 3
    [lzh@hostlzh Ruby]$ ruby 1.rb
    LZH
    Hello,LZH
    ,SB
    [lzh@hostlzh Ruby]$
    • 1
    • 2
    • 3
    • 4
    • 5

    (哇,真的很OOP)


    gets()会留下换行符号的,如果不想要,再.chomp()一下:

    #!/usr/bin/ruby
    name=STDIN.gets().chomp()
    puts("Hello,#{name},SB")
    • 1
    • 2
    • 3
    [lzh@hostlzh Ruby]$ ruby 1.rb
    LZH
    Hello,LZH,SB
    [lzh@hostlzh Ruby]$
    • 1
    • 2
    • 3
    • 4

    标准输出

    puts实际上是STDOUT的puts()方法:

    #!/usr/bin/ruby
    name=STDIN.gets().chomp()
    STDOUT.puts("Hello,#{name},SB")
    • 1
    • 2
    • 3
    [lzh@hostlzh Ruby]$ ruby 1.rb
    LZH
    Hello,LZH,SB
    [lzh@hostlzh Ruby]$
    • 1
    • 2
    • 3
    • 4

    如果不要尾接换行符,用STDOUT的print()方法:

    #!/usr/bin/ruby
    name=STDIN.gets().chomp()
    STDOUT.print("Hello,#{name},SB")
    • 1
    • 2
    • 3
    [lzh@hostlzh Ruby]$ ruby 1.rb
    LZH
    Hello,LZH,SB[lzh@hostlzh Ruby]$
    • 1
    • 2
    • 3

    Ruby提供了类似C语言的格式化输出方法,也是使用占位符:

    #!/usr/bin/ruby
    name=STDIN.gets().chomp()
    STDOUT.printf("Hello,%s,SB%d",name,1)
    • 1
    • 2
    • 3
    [lzh@hostlzh Ruby]$ ruby 1.rb
    lzh
    Hello,lzh,SB1[lzh@hostlzh Ruby]$
    • 1
    • 2
    • 3

    文件输入输出

    也即文件读写,在这之前,先写点东西到文件里:

    [lzh@hostlzh Ruby]$ ll -h>tst
    • 1

    看一下:

    [lzh@hostlzh Ruby]$ cat tst
    总用量 32K
    -rw-rw-r--. 1 lzh lzh   63 1月  27 13:32 1.rb
    -rw-rw-r--. 1 lzh lzh   64 1月  27 13:31 1.rb~
    -rw-rw-r--. 1 lzh lzh 1.1K 1月  26 19:52 first.rb
    -rw-rw-r--. 1 lzh lzh 1.1K 1月  26 19:52 first.rb~
    -rw-rw-r--. 1 lzh lzh  150 1月  27 00:23 MyFileSys
    -rw-rw-r--. 1 lzh lzh   15 1月  26 23:32 MyFileSys~
    -rw-rw-r--. 1 lzh lzh  408 1月  27 00:50 sy4.rb
    -rw-rw-r--. 1 lzh lzh  405 1月  27 00:50 sy4.rb~
    -rw-rw-r--. 1 lzh lzh    0 1月  27 13:36 tst
    [lzh@hostlzh Ruby]$
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    读文件内容

    最常用的是File的open()方法。

    #!/usr/bin/ruby
    file=File.open("./tst", "r")
    while (line=file.gets())!=nil
        STDOUT.print(line," 666 66 6 ")
    end
    file.close()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    Ruby中不强制缩进,所以循环这样的语句块需要有end结束。

    nil是Ruby中的一个特殊值,表示对象不存在,当然在这里可以把!=nil去掉。

    用于简单I/O的方法也可用于所有有权限的文件对象,所以可以用line=file.gets()读入文件中的一行,并且带有换行符。

    [lzh@hostlzh Ruby]$ ruby 1.rb
    总用量 32K
     666 66 6 -rw-rw-r--. 1 lzh lzh   63 1月  27 13:32 1.rb
     666 66 6 -rw-rw-r--. 1 lzh lzh   64 1月  27 13:31 1.rb~
     666 66 6 -rw-rw-r--. 1 lzh lzh 1.1K 1月  26 19:52 first.rb
     666 66 6 -rw-rw-r--. 1 lzh lzh 1.1K 1月  26 19:52 first.rb~
     666 66 6 -rw-rw-r--. 1 lzh lzh  150 1月  27 00:23 MyFileSys
     666 66 6 -rw-rw-r--. 1 lzh lzh   15 1月  26 23:32 MyFileSys~
     666 66 6 -rw-rw-r--. 1 lzh lzh  408 1月  27 00:50 sy4.rb
     666 66 6 -rw-rw-r--. 1 lzh lzh  405 1月  27 00:50 sy4.rb~
     666 66 6 -rw-rw-r--. 1 lzh lzh    0 1月  27 13:36 tst
     666 66 6 [lzh@hostlzh Ruby]$
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    另外,也可以使用File.new()方法,传入相同的参数打开文件,但File.new()不能跟块关联。在这个例子里没有区别。

    #!/usr/bin/ruby
    file=File.new("./tst", "r")
    while (line=file.gets())!=nil
        STDOUT.print(line," 666 66 6 ")
    end
    file.close()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    输出是一样的。


    打开文件后,也可以用sysread()方法指定从当前文件指针向后读多少个字符。

    #!/usr/bin/ruby
    f=File.open("tst","r")
    if f!=nil
       str=f.sysread(40) #读入40个字符后,文件指针在第41个字符位置
       STDOUT.puts(str)
    else
       STDOUT.puts("没能成功打开文件")
    end
    f.close()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    [lzh@hostlzh Ruby]$ ruby 1.rb
    总用量 32K
    -rw-rw-r--. 1 lzh lzh   63
    [lzh@hostlzh Ruby]$
    • 1
    • 2
    • 3
    • 4

    可以用IO.readlines()方法读入指定文件的每一行到数组中,不会自带换行符。也不涉及打开文件和文件指针等问题。

    #!/usr/bin/ruby
    arr=IO.readlines("tst")
    STDOUT.puts(arr[0])
    STDOUT.puts(arr[1])
    STDOUT.puts(arr[3])
    STDOUT.puts(arr[1])
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    [lzh@hostlzh Ruby]$ ruby 1.rb
    总用量 32K
    -rw-rw-r--. 1 lzh lzh   63 1月  27 13:32 1.rb
    -rw-rw-r--. 1 lzh lzh 1.1K 1月  26 19:52 first.rb
    -rw-rw-r--. 1 lzh lzh   63 1月  27 13:32 1.rb
    [lzh@hostlzh Ruby]$
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    方法IO.foreach()之于方法IO.readlines(),就如方法File.open()之于方法File.new()。前者都是可以跟块关联的,块具体怎么用后面再学。

    #!/usr/bin/ruby
    IO.foreach("tst"){|line| puts line}
    • 1
    • 2
    [lzh@hostlzh Ruby]$ ruby 1.rb
    总用量 32K
    -rw-rw-r--. 1 lzh lzh   63 1月  27 13:32 1.rb
    -rw-rw-r--. 1 lzh lzh   64 1月  27 13:31 1.rb~
    -rw-rw-r--. 1 lzh lzh 1.1K 1月  26 19:52 first.rb
    -rw-rw-r--. 1 lzh lzh 1.1K 1月  26 19:52 first.rb~
    -rw-rw-r--. 1 lzh lzh  150 1月  27 00:23 MyFileSys
    -rw-rw-r--. 1 lzh lzh   15 1月  26 23:32 MyFileSys~
    -rw-rw-r--. 1 lzh lzh  408 1月  27 00:50 sy4.rb
    -rw-rw-r--. 1 lzh lzh  405 1月  27 00:50 sy4.rb~
    -rw-rw-r--. 1 lzh lzh    0 1月  27 13:36 tst
    [lzh@hostlzh Ruby]$
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    写入文件

    打开的文件对象的syswrite()方法可以向文件写入内容,写入的方式取决与打开时的写方法。

    r+形式的读写模式文件指针会放在开头,写的内容会随指针移动覆盖之前的内容:

    #!/usr/bin/ruby
    f=File.new("tst","r+")
    if f!=nil
       f.syswrite("LZH
    SBSBSBSBSSB
    SBBBBB")
    else
       STDOUT.puts("无法获取文件对象")
    end
    f.close()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    [lzh@hostlzh Ruby]$ ruby 1.rb
    [lzh@hostlzh Ruby]$ cat tst
    LZH
    SBSBSBSBSSB
    SBBBBB--. 1 lzh lzh   63 1月  27 13:32 1.rb
    -rw-rw-r--. 1 lzh lzh   64 1月  27 13:31 1.rb~
    -rw-rw-r--. 1 lzh lzh 1.1K 1月  26 19:52 first.rb
    -rw-rw-r--. 1 lzh lzh 1.1K 1月  26 19:52 first.rb~
    -rw-rw-r--. 1 lzh lzh  150 1月  27 00:23 MyFileSys
    -rw-rw-r--. 1 lzh lzh   15 1月  26 23:32 MyFileSys~
    -rw-rw-r--. 1 lzh lzh  408 1月  27 00:50 sy4.rb
    -rw-rw-r--. 1 lzh lzh  405 1月  27 00:50 sy4.rb~
    -rw-rw-r--. 1 lzh lzh    0 1月  27 13:36 tst
    [lzh@hostlzh Ruby]$
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    w只写模式,或者w+形式的读写模式,都会重写已经存在的文件,或者是新建并未存在的文件。

    #!/usr/bin/ruby
    f=File.new("tst","w+")
    if f!=nil
       f.syswrite("怎么还不放假
    确实 强啊	666")
    else
       STDOUT.puts("无法获取文件对象")
    end
    f.close()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    [lzh@hostlzh Ruby]$ ruby 1.rb
    [lzh@hostlzh Ruby]$ cat tst
    怎么还不放假
    确实 强啊   666[lzh@hostlzh Ruby]$
    • 1
    • 2
    • 3
    • 4

    输出到字符串

    和C语言很像,sprintf()方法可以格式化输出给字符串,当然普通的不需要占位符的也可以用这个方法,所以只有这一个而没有什么”sputs()”这样的方法。

    #!/usr/bin/ruby
    name=STDIN.gets().chomp()
    str=sprintf("Hello,%s,SB%d",name,1)
    STDOUT.puts(str)
    • 1
    • 2
    • 3
    • 4
    [lzh@hostlzh Ruby]$ ruby 1.rb
    1221assad
    Hello,1221assad,SB1
    [lzh@hostlzh Ruby]$
  • 相关阅读:
    CVE-2014-6271 Shellshock 破壳漏洞 复现
    0ctf-ezdoor-复现分析
    phpinfo中敏感信息记录
    未授权访问总结学习
    关于PHP内部类的一些总结学习
    PHP反序列化总结
    SSRF和XSS-filter_var(), preg_match() 和 parse_url()绕过学习
    Java14:你需要知道的新特性
    结构型设计模式
    项目总结
  • 原文地址:https://www.cnblogs.com/klb561/p/8727366.html
Copyright © 2020-2023  润新知