ruby_rubygems - CSDN
ruby 订阅
Ruby,一种简单快捷的面向对象(面向对象程序设计)脚本语言,在20世纪90年代由日本人松本行弘(Yukihiro Matsumoto)开发,遵守GPL协议和Ruby License。它的灵感与特性来自于 Perl、Smalltalk、Eiffel、Ada以及 Lisp 语言。由 Ruby 语言本身还发展出了JRuby(Java平台)、IronRuby(.NET平台)等其他平台的 Ruby 语言替代品。Ruby的作者于1993年2月24日开始编写Ruby,直至1995年12月才正式公开发布于fj(新闻组)。因为Perl发音与6月诞生石pearl(珍珠)相同,因此Ruby以7月诞生石ruby(红宝石)命名。 展开全文
Ruby,一种简单快捷的面向对象(面向对象程序设计)脚本语言,在20世纪90年代由日本人松本行弘(Yukihiro Matsumoto)开发,遵守GPL协议和Ruby License。它的灵感与特性来自于 Perl、Smalltalk、Eiffel、Ada以及 Lisp 语言。由 Ruby 语言本身还发展出了JRuby(Java平台)、IronRuby(.NET平台)等其他平台的 Ruby 语言替代品。Ruby的作者于1993年2月24日开始编写Ruby,直至1995年12月才正式公开发布于fj(新闻组)。因为Perl发音与6月诞生石pearl(珍珠)相同,因此Ruby以7月诞生石ruby(红宝石)命名。
信息
发布时间
1995年12月
音标(美)
[ˈrubi]
最新版本
2.6.3-preview1
适用平台
跨平台
类    别
脚本语言
词条名
Ruby
中文名
Ruby
创始人
松本行弘
外文名
Ruby
Ruby发展历程
Ruby明显比其他类似的编程语言(如Perl或Python)年轻,又因为Ruby是日本人发明的,所以早期的非日文资料和程序都比较贫乏,所以在网上仍然可以找到类似“Ruby的资料太少”之类的批评。约于2000年,Ruby开始进入美国,英文的资料开始发展。Ruby归根结底源于Perl和Lisp两类语言,与C,C++,C#,java是不同大类。 2011年10月31日1.9.3的第一个稳定版本1.9.3p0发布。2013年2月22日发布了Ruby 1.9.3-p392。2013年2月24日发布了Ruby 2.0.0-p0。2015年4月13日发布了Ruby 2.2.2。2015年12月25日发布了Ruby 2.3.0。最新稳定版本为:Ruby2.4.2
收起全文
精华内容
参与话题
  • Ruby快速入门(30分钟)

    万次阅读 多人点赞 2019-07-02 09:01:31
    在本教程中,将探讨使用Ruby开始编程所需的基本语法,以及如何在30分钟内学习并使用Ruby编程语言。注:如果您还尚未安装Ruby开发环境,请访问环境设置页面并按照说明安装: ...

    在本教程中,将探讨使用Ruby开始编程所需的基本语法,以及如何在30分钟内学习并使用Ruby编程语言。

    注:如果您还尚未安装Ruby开发环境,请访问环境设置页面并按照说明安装: http://www.yiibai.com/ruby/ruby-installation.html

    Ruby历史

    Ruby被许多人认为是一种“新”编程语言,但实际上是由一个叫作Matz的开发人员于1994年发布的。 Matz自我描述是一个“语言极客”,也是Perl大粉丝。 他对Ruby的想法是创建一种像Perl这样灵活而强大的语言,但在其语法上更具表现力 - 甚至可以具有类似于英语那样的可读性。

    Ruby在日本迅速成长,直到2000年,真的没有关于除了日本语言以外的任何文档。所以如果想要学习Ruby,那得必须先学习日语。 敏捷编程的先驱Dave Thomas被Ruby迷住,并决定创建Ruby的其它语言文档。

    自Ruby有了英文开始,Ruby就开始在英语世界中增长,尽管缓慢。 系统管理员变得流行,编写维护和“粘贴”脚本 - 类似Perl的用法。从2000年到2005年美国的Ruby社区已达数百个。

    在2004-2005年,一家名为37Signals的芝加哥公司聘请了一名年轻的开发人员来构建一个Web应用程序。 公司给了他几乎完全的执行自由; 他们只关心客户端的设计和功能。 当时主要的Web技术是Perl CGI,PHP,Java的JSP和Microsoft的ASP。 但是他们都是有点痛苦,但DHH的**大卫(DHH)**选择了自己的方向。他在Ruby中写了这个应用程序。 他依靠核心库和少数库的帮助下,同时自己创建了整个堆栈(或多或少)。37Signals在Web应用程序使用Ruby来编写,这个项目今天被称为Basecamp

    当建立了Basecamp,DHH就会从中提取出Web框架。 这是一个非常不同的方法,从Java/Sun.NET/Microsoft,Web框架都是从高处往下传播。 相反,Rails从现实世界中抽出来。 它侧重于常规配置,使常见问题更容易解决。

    这种方法是一个很大的打击,Rails自从以来一直推动了Ruby/Rails社区的发展。 现在,在亚马逊上有数十本书,全球近一百个会议,有成千上万的人是Ruby/Rails开发人员。

    如果你想学习Rails,需要先学习Ruby! 现在就开始咯 …

    1. Ruby解释器

    Ruby是一种“解释”的编程语言,它不能直接在处理器上运行,它的代码必须馈送到称为“虚拟机”或虚拟机的中间件。 虚拟机的一方面是Ruby代码,另一方面则是操作系统和处理器。 这种方法的好处是您可以编写一次Ruby代码,就可以在许多不同的操作系统和硬件平台上执行了。

    Ruby程序无法运行自己的程序,它需要加载虚拟机。 使用VM执行Ruby的方式有两种:通过IRB和命令行。

    从命令行运行Ruby代码

    这是编写Ruby代码的耐用方法,因为要将指令保存到文件中。 该文件可以备份,传输,添加到源代码管理等。

    一个Ruby代码文件示例

    这里创建一个名称为:first-ruby.rb的文件,如下所示:

    #!/usr/bin/ruby   
    # filename : first-ruby.rb
    
    class Sample
      def hello
        puts "Hello, World!"
      end
    end
    
    s = Sample.new
    s.hello
    

    那么可以这样运行程序:

    当您运行ruby first-ruby.rb时,实际上正在加载ruby虚拟机,然后再加载first-ruby.rb文件中的代码。

    从IRB运行Ruby代码

    Ruby是第一批语言推广所谓“REPL”:阅读,评估,打印,循环的编程语言。想像它就像一个计算器 - 就像在每个完整的指令中,IRB执行这些指令并显示结果。

    IRB最好用作实验的便笺簿。 许多开发人员在编写他们的“真实”程序时,一般都保持IRB窗口打开,使用它来记住某个方法如何工作或用于调试某个代码块。

    要打开IRB进行实验,可通过打开终端(Mac)或命令提示符(Win)并打开或输入irb来启动IRB。以Windows系统为例,如下所示 -

    注: 按 Ctrl + D 可退出 irb 模式。

    2. Ruby变量

    编程都是要创建抽象的代码来描述和处理数据,要创建抽象,必须要为在代码中分配名称来表示事物。 变量只不过是为数据创建一个名称的一种方式。

    创建和分配变量

    在某些语言中,需要在为一个变量分配值之前声明这个变量。 当为变量分配值时,会自动创建Ruby变量。下面来试试一个例子:

    a = 250表示创建一个名称为a的变量,并将值250存储到其中。

    右边优先

    在英文表达式中,是从左到右阅读,所以从左到右读取代码是很自然的。 但是当使用单个等于号(=)评估求值一个赋值时,Ruby实际上首先评估求值右侧。 举个例子:

    irb(main):010:0> b = 10 + 20
    => 30
    irb(main):011:0> b
    => 30
    irb(main):012:0>
    

    上面示例中,首先对10 + 20进行评估求值,再将求值结果存储到b变量中。

    灵活输入

    Ruby的变量可以容纳任何类型的数据,甚至可以更改其持有的数据类型。 例如:

    irb(main):012:0> c = 200
    => 200
    irb(main):013:0> c = "Flexible Typing"
    => "Flexible Typing"
    irb(main):014:0> c
    => "Flexible Typing"
    irb(main):015:0> c = 0.0001
    => 0.0001
    irb(main):016:0> c
    => 0.0001
    irb(main):017:0>
    

    第一次赋予c变量为一个200的整数值。第二次赋值是将c变量的值更改其为“Flexible Typing”。

    命名变量

    大多数Ruby变量(局部变量)的命名都有一些由VM强制的要求。这些要求约定如下 -

    • 始终以小写字母开头(允许下划线,虽然不常见)
    • 不能使用空格
    • 不要包含特殊字符,如$@

    除了那些虚拟机的要求,Ruby开发者对变量名称有几个常见风格偏好:

    • 使用蛇形大小写,即:名称中的每个字都是小写字母,并用下划线(_)连接
    • 以其内容的含义命名,而不是其内容的类型
    • 不使用缩写

    好的变量名的示例如下:counttotal_productsstudents_in_classfirst_lesson

    一些不好的Ruby变量名称的几个例子,如下所示:

    • studentsInClass – 使用骆驼案而不是蛇形大小写,应该命名为:students_in_class
    • 1st_lesson – 变量不能以数字开头,应该命名为:first_lesson
    • students_array – 包括名称的数据类型,应该命名为:students
    • sts – 不使用缩写,应该命名为:students

    练习

    使用IRB存储每个以下变量名称的值。 哪些名字是好的,哪些是是无效的Ruby变量名称,哪些是有效的,哪些是Ruby不建议使用的风格?

    • time_machine
    • student_count_integer
    • homeworkAssignment
    • 3_sections
    • top_ppl

    3. 字符串

    在现实世界中,字符串是将一个个字符串联起来的。 编程中的字符串与真实字符串无关。

    编程中的字符串用于存储字母和数字的集合。它可以是一个单一的字母,如“a”,或者像“hi”这样一个单词,或者“Hello my friends.”这样的一段话。

    编写一个字符串

    Ruby字符串被定义为一个引号("),后跟零个或多个字母,数字或符号,后跟一个闭包引号(")。 最短的字符串称为空字符串:""。 单个字符串包含文本的段落甚至页面也很常见。

    子字符串

    通常使用字符串,可从整个长字符串提取出来的一部分 - 这提取出来的部分称为子字符串。在 irb 尝试这些例子:

    irb(main):017:0> string = "Ruby in 30 Minutes at yiibai.com"
    => "Ruby in 30 Minutes at yiibai.com"
    irb(main):018:0> string[0..8]
    => "Ruby in 3"
    irb(main):019:0> string[8..16]
    => "30 Minute"
    irb(main):020:0> string[8..-1]
    => "30 Minutes at yiibai.com"
    irb(main):021:0> string[8..-2]
    => "30 Minutes at yiibai.co"
    irb(main):022:0>
    

    正号和负号的位置

    字符串中的字符每个都有一个位置编号,它们从零开始。 所以对于字符串中的开头“Ru”,“R”位置编号为0,“u”所在的位置编号为1

    要在主字符串中提取出一个子串,可指定提取的起始位置和结束位置。 因此,上面的string[0..8]提取出位置从08的字母,也就是:“Ruby in 3”。

    Ruby解释负的位置从字符串的末尾返回。所以在上面示例中,结尾的字符串“com”的字母分别对应为“m”位于-1,“o”位于-2 和 “c”位于-3

    所以如果一个字母同时有正数和负数的位置,那么应该使用哪个? 建议使用正数,因为这样它们更容易理解。 但是,如果要基于字符串末尾查找东西(例如“该字符串的最后一个字符是什么?”),则使用负数指定位置。

    常用的字符串方法

    在IRB中使用字符串(对象)中一些常用的方法。

    .length

    length方法用于求出字符串中有多少个字符(包括空格):

    irb(main):022:0> string = "0123456789"
    => "0123456789"
    irb(main):023:0> string.length
    => 10
    irb(main):024:0> string = "maxsu"
    => "maxsu"
    irb(main):025:0> string.length
    => 5
    irb(main):026:0>
    

    尝试:计算你的名字的总长度

    .split

    有时想要将一个字符串分成几部分。 例如,假设有一个存储为字符串的句子,并将其分解成单词:

    C:\Users\Administrator>irb
    irb(main):001:0> string = "This is my sample sentence."
    => "This is my sample sentence."
    irb(main):002:0> string.split
    => ["This", "is", "my", "sample", "sentence."]
    irb(main):003:0>
    

    .split方法返回一个数组,这将在后面的部分讲解中了解到。 它默认使用空格(“”)字符将字符串分割成多个部分。

    .split使用参数

    但有时要分割的不是一个带有空格的字符。 .split方法接受一个参数来指定分隔符,看看下面示例就明白了。

    irb(main):003:0> numbers = "1,2,3,4,5,6,7,8"
    => "1,2,3,4,5,6,7,8"
    irb(main):004:0> numbers.split
    => ["1,2,3,4,5,6,7,8"]
    irb(main):005:0> numbers.split(",")
    => ["1", "2", "3", "4", "5", "6", "7", "8"]
    irb(main):006:0>
    

    在第一次分割的调用中,它尝试使用空格作为分隔符,但字符串中没有分隔符,所以得到一个整个字符串的数组。 在第二次尝试中,指定使用逗号(",")作为分隔符,所以得到一个8个数字值的数组。

    .sub 和 .gsub

    这两种方法可以用来替换字符串的部分。它们就像在文字处理器中使用“查找和替换”。 .sub替换只发生一次。 而.gsub全局替换的缩写,替换所有的发生(如“全部替换”)。

    对于.sub.gsub,需要指定两个参数:首先是要替换的子字符串,然后再替换要替换的字符串。

    irb(main):013:0> greeting = "Hello, Hello Everyone!"
    => "Hello, Hello Everyone!"
    irb(main):014:0> greeting.sub("Hello","Hi")
    => "Hi, Hello Everyone!"
    irb(main):015:0> greeting.gsub("Hello","Hi")
    => "Hi, Hi Everyone!"
    irb(main):016:0>
    

    组合字符串和变量

    将变量的值与字符串相结合这是在开发应用程序中最经常使用的。 例如,现在从下面这个例子开始:

    "Good morning, ?? !"
    

    当把上面语句放入IRB时,它只是打印输出同一个字符串。 如果编写一个应用程序,希望它以用户名而不是“??”来跟用户打招呼,那么需要怎么做?

    需要做的就是将变量与字符串组合。有两种方法可以做到这一点。

    方法-1. 字符串连接

    第一种方法,可使用字符串连接,它将字符串与加号连接:

    irb(main):021:0> name = "Maxsu"
    => "Maxsu"
    irb(main):022:0> puts "Good morning, " + name + " ! "
    Good morning, Maxsu !
    => nil
    irb(main):023:0>
    

    在第一行中,设置了一个name变量来保存名称。 在第二行,打印字符串“Good morning" 并结合"name“变量和字符串”!"的值。

    方法-2. 字符串插值

    第二种方法是使用字符串插值,将数据粘贴到字符串的中间。

    字符串插值仅适用于双引号字符串。在字符串内使用插值标记#{}。 在这些括号中可以把任何变量或Ruby代码放入其中,这些变量或Ruby代码将被评估求值,其结果转换为一个字符串,并输出到外部字符串的那个位置。 上面的例子可以这样重写:

    irb(main):023:0> name = "Maxsu"
    => "Maxsu"
    irb(main):024:0> puts "Good morning, #{name}!"
    Good morning, Maxsu!
    => nil
    irb(main):025:0>
    

    如果比较输出结果,就会看到它们输出的是完全相同的结果。 内插样式往往是输入较少的字符类型,较少的双引号打开/关闭,所以可避免加双引号时忘记书写对称(往往有输入多一个,少一个的问题)。

    内插插入代码

    还可以将任何Ruby代码或计算表达式内置在括号内,如下所示:

    irb(main):025:0> modifier = "very "
    => "very "
    irb(main):026:0> mood = "excited"
    => "excited"
    irb(main):028:0> puts "I am #{modifier * 3 + mood} for today's play!"
    I am very very very excited for today's play!
    => nil
    irb(main):029:0>
    

    首先对#{modifier * 3 + mood}代码块进行评估求值,然后将结果注入外部字符串中。

    4. 符号

    符号有点难以解释,它们是字符串和数字的一半。但是可以很容易识别一个符号,因为它是以冒号开始一个或多个字母,如:flag:best_friend

    新程序员的符号

    如果你是编程的新手,可将一个符号看作是一个几乎没有任何方法和没有字符串插值的被剥离下来的字符串。 将正确的字符串与类似符号的方法列表进行比较,如下所示:

    2.1.1 :001> "hello".methods
    2.1.1 :002> "hello".methods.count
    2.1.1 :003> :hello.methods
    2.1.1 :004> :hello.methods.count
    

    有经验的程序员的符号

    如果你是一个有经验的程序员,想象一个符号是一个“命名整数”。 符号引用的实际值无关紧要。 我们所关心的是,虚拟机内对该值的任何引用将返回相同的值。 因此,符号在全局符号表中定义,它们的值不能改变。

    5. 数字值

    数字有两种基本类型:整数(整数)和浮点数(有小数点)。
    整数对于您和计算机来说都要容易一些。 您可以使用包括+-/*在内的整数的正常数学运算。 整数有一些方法可以用来做数学相关的事情,过调用5.methods方法就可看到一些常用的方法。

    重复指令

    重复执行指令在其他语言中的常见模式是for循环,用于重复执行某些指令一定次数。 例如,在JavaScript中可以写:

    for(var i = 0; i < 5; i++){
      console.log("Hello, World");
    }
    

    对于循环是很常见的,但它们的代码不是很容易阅读。 因为Ruby的整数是它们拥有方法的对象。 其中的一个方法:times是重复执行指令的方法。

    以Ruby样式重写上述循环:

    5.times do
      puts "Hello, World!"
    end
    

    在这个例子中,使用times方法和具体的执行代码块。 在下一节中将讨论块。 但是请先在IRB中运行这个例子,看看结果会是什么。

    6. 块

    块是Ruby中经常使用的强大概念。 可将块视为一组捆绑在其他地方使用的指令的方式。

    块的开始和结束

    在上一节中有一个使用.times方法的块用整数表示:

    5.times do
      puts "Hello, World!"
    end
    

    该块以关键字do开始,以关键字end结束。 do/end风格总是可以被Ruby解释器所接受的。

    支架块

    当块仅包含单个指令时,经常使用备用标记{}来标识块的开始和结束:

    5.times{ puts "Hello, World!" }
    

    块被传递给方法

    那么使用块来做什么? 块可以用来作为传递给方法调用的参数。

    例如,如果调用了5.times,Ruby就不会知道要执行五次了。当通过块时,就会说“这里是希望每次运行的说明”。

    块中有很多的方法。 就像前面看到的.gsub方法一样,字符串早就为每个匹配运行一个块:

    irb(main):038:0> "this is a sentence".gsub("e"){ puts "Found an E!"}
    Found an E!
    Found an E!
    Found an E!
    => "this is a sntnc"
    irb(main):039:0>
    

    请注意,"Found an E!"显示了三次,因为字符串中有三个E字母。

    块参数

    通常,在块内指示需要引用正在使用的值。 当在编写块代码时,可以在管道字符中指定一个块参数:

    5.times do |i|
      puts "Hello, World! "
    end
    

    什么值应该放入该块参数,这取决于要调用的方法。 在本示例中,times方法放入当前运行的数值。尝试上面的块,观察输出,然后尝试这样修改:

    5.times do |i|
      puts "#{i}: Hello, World!"
    end
    

    上面代码输出结果如下 -

    irb(main):045:0> 5.times do |i|
    irb(main):046:1*   puts "#{i}: Hello, World!"
    irb(main):047:1> end
    0: Hello, World!
    1: Hello, World!
    2: Hello, World!
    3: Hello, World!
    4: Hello, World!
    => 5
    irb(main):048:0>
    

    .gsub在找到的字符串中传递。 尝试这个(用括号表示法):

    irb(main):048:0> "this is a sentence".gsub("e"){|letter| letter.upcase}
    => "this is a sEntEncE"
    irb(main):049:0>
    

    在上面结果中看到gsub正在使用块的结果作为原始匹配的替换。

    7.数组

    通常当编写程序时,我们需要处理数据的集合。先来看看最常见的数据集合 - 数组。

    可视化模型

    数组是数字索引列表。 想象一下,有一张空白的纸,画了三个小盒子:

     ---  ---  ---
    |   ||   ||   |
     ---  ---  ---
    

    可以按照从左到右对每一个位置进行编号:

     ---  ---  ---
    |   ||   ||   |
     ---  ---  ---
      0    1    2
    

    然后在每个框中放入字符串(或其它值):

     -------------  ---------  ----------
    | "Breakfast" || "Lunch" || "Dinner" |
     -------------  ---------  ----------
           0            1           2
    

    现在变成一个有三元素的数组。 Ruby数组的大小可以增长和缩小,所以如果添加一个元素,它通常会在结束位置添加,索引值也会变递增1

     -------------  ---------  ----------  -----------
    | "Breakfast" || "Lunch" || "Dinner" || "Dessert" |
     -------------  ---------  ----------  -----------
           0            1           2           3
    

    请注意,最后一个元素的位置总是比元素的数量小1

    数组中在索引为2位置对应的数据值为“Dinner”。最后一个元素对应的数据值为“Dessert”。

    代码中的数组

    以下是Ruby代码中相同建模的方法:

    irb(main):049:0> meals = ["Breakfast", "Lunch", "Dinner"]
    => ["Breakfast", "Lunch", "Dinner"]
    irb(main):050:0> meals << "Dessert"
    => ["Breakfast", "Lunch", "Dinner", "Dessert"]
    irb(main):051:0> meals[2]
    => "Dinner"
    irb(main):052:0> meals.last
    => "Dessert"
    irb(main):053:0>
    

    在上面代码运行结果中,观察到…

    • 该数组是通过将数据片段放在方括号([])之间并用逗号分隔来创建的。

    • 通过使用“铲子运算符”(<<)添加一个元素到数组的末尾

    • 通过使用方括号([])在指定索引位置来获取元素

    • 数组中一些方便的方法,如.last

    常用数组方法

    数组有很多很酷的东西。 以下是几个例子:

    .sort方法

    sort方法将返回一个新的数组,其中元素是已经被排序过了。 如果元素是字符串,它们将以字母顺序返回。 如果它们是数字,它们将按升值顺序回来。尝试下面示例:

    irb(main):056:0> array1 = ["this", "is", "an", "array"]
    => ["this", "is", "an", "array"]
    irb(main):057:0> array1.sort
    => ["an", "array", "is", "this"]
    irb(main):058:0> array1
    => ["this", "is", "an", "array"]
    irb(main):059:0>
    

    可以使用sort方法重新排列元素的顺序。使用each方法遍历每个元素。使用join方法将它们一起混合成一个字符串。使用index方法找到特定元素的地址。可以使用include?方法询问数组是否包含指定的元素。

    使用数组只要需要一个列表,其中元素是以特定的顺序排序的。

    其他的尝试

    在数组上尝试下面这些常见的方法:

    • each
    • collect
    • firstlast
    • shuffle

    可以参考这个文档了解更多详细信息:http://www.ruby-doc.org/core-2.1.2/Array.html

    8.哈希

    哈希是数据的集合,哈希中的数据的每个元素是按名称来寻址。作为一个比喻,想一下冰箱。 如果要跟踪放在冰箱内的东西,我们并不关心它的放在哪里 - 顺序并不重要。 相反只是按名称去组织这些东西。如名称“apples”可能具有值3,则名称“oranges”可能具有值1,并且“carrots”值为12。 在本示例中,就可使用哈希。

    键/值对

    哈希是无序的集合,其中数据被组织成“键/值对”。 哈希的语法更复杂,需要一些习惯:

    irb(main):001:0> produce = {"apples" => 3, "oranges" => 1, "carrots" => 12}
    => {"apples"=>3, "oranges"=>1, "carrots"=>12}
    <e are #{produce['oranges']} oranges in the fridge."
    There are 1 oranges in the fridge.
    => nil
    irb(main):003:0>
    

    键用作为地址,值是该地址的数据。 在produce哈希中有包括“apples”和“oranges”的键,其值分别为123。当创建哈希时,键和值使用=>符号链接。 所以哈希从一个大括号{开始,(由一个键,一个=>标识符和一个由逗号分隔的值组成的零个或多个条目,然后以一个关闭的大括号}结束。

    再尝试一些代码:

    irb(main):006:0> produce["grapes"] = 219
    => 219
    irb(main):007:0> produce
    => {"grapes"=>219}
    irb(main):008:0> produce["oranges"] = 66
    => 66
    irb(main):009:0> produce
    => {"grapes"=>219, "oranges"=>66}
    irb(main):010:0> produce.keys
    => ["grapes", "oranges"]
    irb(main):011:0> produce.values
    => [219, 66]
    irb(main):012:0>
    

    在这些说明的第一行中,向哈希添加了一个新值。 由于“grapes”键不在原始哈希中,所以它的值为221。 哈希中的键必须是唯一的,所以当对product [“oranges”]使用相同的语法时,它会看到键“oranges”已经在列表中,并且用6替换值。keysvalues方法会列出所有键和值。

    简化哈希语法

    通常会使用符号作为哈希的键。 当所有的键都是符号时,可以使用一个速记语法:

    irb(main):012:0> produce = {apples: 3, oranges: 1, carrots: 12}
    => {:apples=>3, :oranges=>1, :carrots=>12}
    irb(main):013:0> puts "There are #{produce[:oranges]} oranges in the fridge."
    There are 1 oranges in the fridge.
    => nil
    irb(main):014:0>
    

    请注意,键以冒号结尾,而不是以冒号开始,即使这些是符号。 这个简化的语法能在Ruby 1.9及更高版本配合使用。要了解正在使用的是哪个版本的Ruby,可在控制台中输入“ruby -v”。

    9. 条件

    条件语句评估求值结果为truefalse。 最常见的条件运算符是==(相等),>(大于),>=(大于或等于),<(小于)和<=(小于或等于)。

    一些对象也有返回truefalse的方法,因此它们在条件语句中使用。 例如,每个对象都有方法.nil? 只有当对象为nil时才返回:true。 数组有一个名称为.include的方法 如果数组包含指定的元素,则返回true。 Ruby中的约定方法名称以结尾返回truefalse

    条件分支/指令

    为什么要有条件语句? 最常见的是控制条件指令,特别是:if/elsif/else结构。在IRB中添加一个这样的方法来写一个例子:

    def water_status(minutes)
      if minutes < 7
        puts "The water is not boiling yet."
      elsif minutes == 7
        puts "It's just barely boiling"
      elsif minutes == 8
        puts "It's boiling!"
      else
        puts "Hot! Hot! Hot!"
      end
    end
    
    # run method with difference parameter
    water_status(5)
    water_status(7)
    water_status(8)
    water_status(9)
    

    尝试使用:water_status(5)water_status(7)water_status(8)water_status(9)运行该方法。

    理解执行流程

    minutes值为5时,执行结果是什么?因为minutes = 5小于7,所以打印出来的结果为:“The water is not boiling yet.

    minutes值为7时,执行结果是什么?因为minutes值等于7,所以打印出来的结果为:“It's just barely boiling

    minutes值为8时,执行结果是什么?因为minutes值等于8,所以打印出来的结果为:“It's boiling!

    minutes值为9时,执行结果是什么?因为minutes = 9,它比较了前面的几个值:578,但是都没有匹配项,所以最后执行到else语句块中,打印出来的结果为:“Hot! Hot! Hot!

    if语句可能的结构

    if语句有以下可能的结构:

    • if语句的指令只有在语句为真时执行。
    • if语句后面可有零或多个elsif语句,其指令仅在语句为真时执行
    • if语句后面零或一个else语句,如果没有一个ifelsif语句为真,则执行else语句中的指令。

    if/else if/else结构中只能在一个部分可以运行它的指令。例如,如果if是真的,Ruby将永远不会执行elseifelse,也就是说永远只执行其中一块。

    相等与分配值

    编写条件语句时遇到常见错误是书写===,以及它们的区别。

    • =符号表示赋值。表示“拿右边的东西,把它粘在左边的任何东西”
    • ==表示为这是一个问题。表示“右边的东西是等于左边的东西吗?”

    还可以使用逻辑运算符组合条件语句。 最常见的是“逻辑与”和“逻辑或”。 在Ruby中,您可以使用这样的双符号(&&)来书写表示一个“逻辑和”。可以用这样的双管道(||)书写表示一个“逻辑或”。

    10. Nil和虚无

    什么是虚无? 当我们表达一个东西,没有确定它是什么东西的暂时可以叫它为:虚无,不是没有什么东西吗? 好的,这太多哲学了,这有确实点难解释了。

    nil是Ruby中用于表达“虚无”的方式。

    如果有三个鸡蛋,您吃三个鸡蛋,那么可能认为现在您“没有什么”蛋了,但是在鸡蛋方面有“0”个。0是什么?它是一个数字,它并不是“虚无”。

    如果使用一个单词,如“hello”这样的字符串,那么删除“h”,“e”,“l”和“o”,你可能会认为没有什么,但是现在真的有“”,它是一个空字符串,并不是“虚无”。

    nil是Ruby的虚无的想法的表示。 当要求不存在的东西时,通常会遇到这种情况。 例如,当查看数组时,创建了一个包含五个元素的列表,然后要获取列表中添加第六个元素。但是没有第六个元素,所以Ruby给了nil。 在第六个元素的地方它并不是空白(“”),也不是数字0,它是空/nil

    编写Ruby代码时遇到的大部分错误是涉及nil值的。以为某个位置有数据值,试图使用使用这个数据值去做一些事情,但没有这样的数据值,不能做任何事情,所以Ruby引发了一个错误。

    11. 对象,属性和方法

    Ruby是面向对象的编程语言

    Ruby是一种面向对象的编程语言,在与VM内部交互的所有东西都是对象。 每条数据都是一个对象。 对象保存的信息称为属性,可以执行对象的方法。

    作为一个对象的例子,想像你是一个人。 你有像高度,重量和眼睛颜色的属性。 你有“走路”,“跑步”,“洗碗”和“白日梦”的方法。不同类型的对象具有不同的属性和方法。 在接下来的章节中,将介绍一些Ruby中常见的特定类型的对象。

    类和实例

    在面向对象编程中,我们定义了类,它们是类别或类型的东西的抽象描述。 它定义了该类型的所有对象的属性和方法。

    定义一个类

    例如,考虑对一个学校信息建模。要创建一个名为“Student”的类,表示学生的抽象。 Student类将定义如:first_namelast_nameprimary_phone_number的属性。 它可以定义一个用于学生自我介绍的方法:introduction

    尝试在IRB编写上面代码:

    class Student
      attr_accessor :first_name, :last_name, :primary_phone_number
    
      def introduction
        puts "Hi, I'm #{first_name}!"
      end
    end
    

    attr_accessor方法是用于定义类的实例的属性。

    创建类的实例

    Student类本身不代表学生,这是学生信息表示模型。 要表示一个实际的学生,需要创建一个Student类的实例。

    想像你就是一个学生,不是一个抽象的概念,因为你是一个实际的人。这个实际的人是Student类的一个实例 - 它是一个抽象思想的实现。一个实际的人具有属性:first_namelast_nameprimary_phone_number 的实际数据(比如:你的first_name是“爱华”,last_name是“”等等)。

    另一方面,Student类有几个抽象的属性: first_namelast_nameprimary_phone_number,我们不能提前确定它们。

    从文件运行Ruby

    一般情况下,很少在IRB中定义类。这是因为IRB只是一个便签本(不能很好的保存代码),记得吗? 下面来看看如何从文件中运行Ruby。

    • 退出IRB会话(输入:exitCtrl + D)
    • 注意终端当前在哪个文件夹,进入你的“工作目录”(本教程中,代码都是写在:F:\worksp\ruby)
    • 使用纯文本编辑器创建一个名为student.rb的文件。
    • 将文件保存在student.rb文件中。
    • 从终端运行文件:
    ruby student.rb
    

    由于这个文件是空的,所以不应该得到任何输出。

    创建Student

    在文本编辑器中,开始编写类的结构:

    class Student
    
    end
    

    在类的内部,通常使用def关键字定义一个或多个方法,如下:

    class Student
      def introduction
        puts "Hi, I'm #{first_name}!"
      end
    end
    

    请注意,puts行正在计算求值一个名为first_name的方法,该方法返回学生的名字。下面可以进一步添加之前使用的三个属性:

    class Student
      attr_accessor :first_name, :last_name, :primary_phone_number
    
      def introduction
        puts "Hi, I'm #{first_name}!"
      end
    end
    

    运行文件

    回到终端,尝试用ruby student.rb运行文件。应该不会看到有结果输出。

    这是为什么呢? 上面步骤中已经定义了一个Student类,并表示一个学生有一个名为introduction的方法以及一些属性 - 但是实际上并没有创建Student类的实例或调用任何方法。

    创建实例

    当定义一个类后,还要创建类的一个实例,如下所示:

    frank = Student.new
    

    Student类上调用new方法并将其存储到变量frank中。当有了这个类的实例以后,就可以调用实例的方法来设置或获取其属性。

    使用以下语法调用方法:object.method_name。在上面示例中,创建一个实例变量:frank,现在可以通过调用 frank.introduction 来获取学生的介绍信息了。

    在文件中创建一个实例

    student.rb文件的底部,在Student类的end关键字之后,添加以下内容:

    frank = Student.new
    frank.first_name = "Frank"
    frank.introduction
    

    最终完整的代码如下所示 -

    class Student
      attr_accessor :first_name, :last_name, :primary_phone_number
    
      def introduction
        puts "Hi, I'm #{first_name}!"
      end
    end
    
    frank = Student.new
    frank.first_name = "Max"
    frank.introduction
    

    保存代码并返回到终端,再次执行ruby student.rb。 现在应该输出:“Hi, I'm Max!

    方法参数

    有时,方法使用一个或多个参数来完成一些事情。 例如,可以调用 frank.introduction('Minlee'),让它向Minlee介绍自己。参数可以是数字,字符串或任何种类的对象,下面修改introduction方法,以使用一个参数:

    class Student
      attr_accessor :first_name, :last_name, :primary_phone_number
    
      def introduction(target)
        puts "Hi #{target}, I'm #{first_name}!"
      end
    end
    
    frank = Student.new
    frank.first_name = "Maxsu"
    frank.introduction('Minlee')
    

    保存代码并返回到终端,再次执行ruby student.rb。 现在应该输出:“Hi Minlee, I'm Maxsu!

    返回值

    Ruby中,每次调用方法时都会得到一个值。 默认情况下,Ruby方法返回其评估求值的最后一个表达式的值。

    现在向Stuent类中添加一个方法:favorite_number,如下所示 -

    class Student
      attr_accessor :first_name, :last_name, :primary_phone_number
    
      def introduction(target)
        puts "Hi #{target}, I'm #{first_name}!"
      end
    
      def favorite_number
        7
      end
    end
    
    frank = Student.new
    frank.first_name = "Maxsu"
    puts "Maxsu's favorite number is #{frank.favorite_number}."
    
    

    打开终端运行上面代码,应该看到:“Maxsu's favorite number is 7”。文件的最后一行调用的是favorite_number方法。 该方法的最后一行(只有)行是第7行。这个表达式作为方法的返回值,该值返回给调用该方法的任何人。在例子中,这7数字值返回并被插入到字符串中。

    注意:写在最后,需要注意的是:这篇教程包教不包会!

    展开全文
  • Python和Ruby语言对比

    千次阅读 2012-02-21 15:27:32
    1、python和ruby的相同点: * 都强调语法简单,都具有更一般的表达方式。python是缩进,ruby是类basic的表达。都大量减少了符号。 * 都是动态数据类型。都是有丰富的数据结构。 * 都具有c语言扩展能力,都...

    一、异同对比选择
    1、python和ruby的相同点:

    * 都强调语法简单,都具有更一般的表达方式。python是缩进,ruby是类basic的表达。都大量减少了符号。

    * 都是动态数据类型。都是有丰富的数据结构。

    * 都具有c语言扩展能力,都具有可移植性,比perl的可移植性更好。也都可以作为嵌入语言。

    * 都是面向对象的语言,都可以作为大项目的开发工具。

    * 都有丰富的库支持。

    * 也有最宽松的版权许可,除了一些工具属于GNU世界。

    * 都有lisp特色的eval函数,也都能把函数作为参数。

    * 也有图形界面的ruby的专门编辑器。

    * 都获得了广泛的c库的支持。如qt、gtk、tk、SDL、FOX等,ruby计划实现SWIG接口。

    * 都有完善的文档。

     

    2、和python相比ruby的优点:

    * 具有正则表达式和嵌入html的功能。python也有正则表达式,但没有ruby的应用方便和广泛。python的嵌入html项目才刚起步。ruby还有apache的mod模块。ruby本身也实现和很多unix工具,如racc,doctools。比python更亲近linux。

    * 比python功能更完整的面向对象的语法。 
    * ruby的整个库都是具有类继承的结构。 
    * 他的基本的数据类型和运算符都是可以重载的。 
    * ruby主要的功能都是通过对象的方法调用来实现的,而不是函数。python也在向这方面发展,但没有ruby做的彻底。 
    * ruby的类是更规范的单继承,还有接口等概念的实现。

    * python可以实现在列表内的条件语句、循环语句,而ruby用“块”的方式来实现这个功能,比python的更灵活,更具有通用性。

    * ruby具有类似lisp的彻底的函数方式的条件语句、循环语句等。语句的表达能力更强。

    * 附带一些unix工具,如racc等。

     

    3、和python相比ruby的不足:

    * 最大的不足正是因为ruby的强大所引起的。它没有python的简单性好。比较复杂的面向对象语法、“块”语法的引入、正则表达式的引入、一些简写标记都增加了语言的复杂性。

    * python的缩进表达方式比ruby的basic的表达方式更让人悦目,ruby程序的满眼的end让人不舒服。当然,ruby认为end的方式比python更先进。

    * ruby还没有python的“自省”的能力,没有从程序文件中生成文档的能力。

    * ruby没有国际化的支持。国际化支持在ruby的计划中。这是因为ruby的历史比python要短造成的。

    * ruby没有类似jython的东西。

     

    4、python和ruby的语言的选择:

    从简单的就是好的来说,选python是没错的。python适合寻找简单语言的人,这很可能造成python更流行,因此也有更多的支持。但如果要追求更强大的语法功能,则ruby是好的选择。因为ruby和python的哲学有很多相似的地方,先从python入手,尽量用python,如果python的能力不足了,可以在找ruby。

    ruby和python的比较,就像五笔和拼音输入法的比较。拼音作为入门的输入法和长久使用的输入法都没有问题。五笔适合更高要求的情况。如果追求性能的不妨学学ruby。对编程语言感兴趣,想了解各种编程概念的学ruby也会很兴奋。 


    二、两者各有特点:

      1、Python从语法上来说更质朴一些,而Ruby更性感一些

       Python的语法相对其他脚本语言来说,没有太多花巧的地方,显得比较死板一点,其实从Python强制代码缩进也可以看出来Guido设计语言的取向。语法死板的一面就是不容易玩出来更性感的东西,比方说Rails这样的框架,另外Python也无法做DSL这样的事情,但是语法死板的另一面就是比较规范,相对来说,更加适应软件开发的工程性要求,更容易组织大规模的团队进行开发。

       Ruby的语法非常灵活,Matz设计ruby的出发点也是为了coding for fun,因此可以用ruby玩出来很多花样,运用足够的技巧,可以用Ruby写出来逼近自然语言的DSL,对于程序员来说,玩ruby确实充满了乐趣。Rails能在ruby社区诞生,而不是Python社区诞生绝对和编程语言有直接的关系。不过ruby语法灵活的另一面就是编程实现风格的多样性,这对于大规模团队的协作和管理是一个挑战。

       2、Python的解析器实现更成熟,第三方库质量高

       Ruby1.9解析器尽管已经有了很大的性能提升和很多新的功能,但是从源代码实现的角度来说,基本上是通过在Ruby1.8源代码上打patch来增加功能的。从源代码的结构来说,Ruby的实现太古老了,Ruby扩展起来比较困难,只能不断打patch。这也是为什么现在Ruby社区涌现出来那么多新的Ruby解析器实现的原因。从很大程度上来说,这制约了Ruby的发展速度。相对而言,Python解析器更成熟,也比较稳定。

       在第三方类库的数量上来说,Ruby并不比Python少,但是高性能高质量久经考验的第三方类库Python要明显比Ruby多,事实上很多Ruby的第三方类库都不太成熟,因此这也很大程度上制约了Ruby的发展。

       3、Python的应用领域非常广泛,而Ruby目前主要局限在在Web领域

       Python应用的领域非常广泛,除了web开发以外,还被广泛用在服务器后端的高性能服务器实现,服务器后端的各种密集运算,全文检索,各种文本处理,系统管理等等,另外桌面应用领域wxPython也是一个很成熟的跨平台GUI框架。对于某些特殊的应用,比方说调用操作系统内核API,Python也可以完成的很好,比方说大量小文件的实时同步方案,就是用Python直接调用Linux Kernel的inotify特性来实现的。所以可以说Python是软件开发领域的瑞士军刀,什么事情都可以做。

       正是由于Ruby解析器和Ruby类库的制约,Ruby的应用主要局限在Web开发领域,目前Ruby的应用还无法延伸到web开发领域以外的很多地方。据说豆瓣早期就考虑过Ruby on Rails,但是因为Ruby不能做其他事情,而Python可以大包大揽,最后放弃Ruby选择了Python。

      4、在Web领域Ruby是王者

       随着互联网应用更进一步渗透到软件开发的各个领域,其实web开发占整个软件行业开发的比重也是越来越大。尽管Ruby在其他领域很受制约,但是在Web开发领域就是绝对的王者了。Rails框架的领先程度已经远远甩开了任何一个潜在的竞争对手十万八千里。因此尽管Ruby可能有这样那样的问题,但是说到Web开发,Rails几乎就是无可争议的唯一选择。

       而Python尽管十分全面,却偏偏在web开发领域不彰,web框架虽然众多,却没有一个真正可以挑大梁,Django虽然在Python社区比较流行,但很多方面也有缺陷。现在的互联网应用往往都是多种语言混合编程,Ruby在Web以外的缺陷也可以用其他语言来弥补。

       5、Python的包管理不如Ruby

       尽管Python的第三方类库更高质量更成熟,但是Python社区缺乏Ruby Gem这样一个良好的包管理软件和包发布的网站。因此应用的构建显得不如Ruby那么方便,那么人性化。特别是在类库的版本升级上,就会遇到很多麻烦,不如Ruby Gem那么简单。

       不过总的来说,Python和Ruby还是相似度极高的两种编程语言,即使两种编程语言都学习一下也不会浪费太多时间。如果我个人选择的话,会首选用Rails来构建web应用,再根据情况选择Python或者Java处理一些服务器后端的运算。总之,未来还是一个混合编程的时代,我们需要多了解一些编程工具,然后根据需要看菜吃饭才行。

    三、《ruby和python的比较》之更正

       1、文档、开源项目、库支持,这些东西Ruby不要跟Python比,不是几个数量级的问题,何必貌似并列的排在一起。
       2、Python确实没有把正则表达式模块内置到核心里面,但是却有re这个标准库的支持,当时的目的也是为了尽可能的把核心做到最小。我不太明白,使用标准库和内置有什么区别,甚至可以作为优点?且使用Python中的正则表达式也不过是多个import 
            re和调用时的几个字母而已,省下的无数个end足以抵销这个问题了。
       3、至于嵌入HTML功能,Python里有C/Python双实现的Cheetah模板可用,据说托Zope的福,美国海军和法国政府在用,不知Ruby这个功能的成熟度如何?
       4、mod_ruby模块的出现时间很短,如果作者没有听过mod_python那就实在孤陋寡闻了。我在一年前翻译mod_python3.2.8文档的时候,mod_python已经很成熟了,以至于几乎所有的Python 
            WEB框架都支持构建在其上来提高效率。但是,似乎mod_ruby的更新,每年也只有几次。mod_python更有gnu.org这样的重量级应用,不知mod_ruby有没有?
       5、另外,提到unix工具。Red hat 
            Linux的安装程序一直是用Python写的,如果你恰巧用ubuntu,那么,那个提示你更新系统的程序,也是用Python写的。
        6、racc和doctools,请原谅我的孤陋寡闻,我google了一下居然除了你的这篇文章还没找到几篇关于racc的中文内容,辗转之后才查到是一种类似yacc的工具。从google的角度讲,racc的可用性我就不多说了。我不太明白一个yacc工具在日常编程当中有多大的实用性,但是既然作者提到了我就顺便找了个我只听说过名字,根本没用过的spark。google的结果是"racc 
            ruby":"python 
            spark"=159,000:659,000。至于doctools,我更是无话可说,在google上只有15,800条记录,我到现在都看不出这个东西是干什么用的。所以找了个估计是类似的东西对比了一下,docutils,google的记录是25,400条。
        7、“比Python库更完整的面向对象语法”。试问面向对象的目的是什么?再者,ruby能否像Python一样,绝大多数标准库根本不需要查文档,只要猜测一下大体上的名字,然后dir()一下,再help()一下就可以直接上手,用到第二次的时候,因为模块内东西实在太少,记忆太方便,就可以直接写出来的地步?另外,面向对象既不是什么银弹,也不是最先进的软件工程思想。
        8、"ruby的整个库都是类继承结构的",个人认为是Java的糟粕,反倒是当成宝学过来了。或许这也是ruby来拯救Java程序员的一项优势吧。
         9、"基本数据类型和运算符都是可以重载的",这个不是太清楚,不知Python中重载__add__之类的算不算。
         10、"ruby主要的功能都是通过对象的方法调用来实现的,而不是函数",Python中所有的东西都是对象,但并不都是类,不知这句还有什么意义。另外,推荐你不要太追求什么彻底,还是实用这个词比较有吸引力。
         11、Python没有严格要求单继承是给程序员以灵活性。另外,关于接口,Python中只要定义了同名的函数就算是具有了相同的接口,玄学上升到了这个高度,我也有些迷糊了。至于接口,不要那么自信,ruby的所谓接口也不过是个mix-in。这个东西Python的几个大项目中也有过实现,只是因为对Python意义不明显,所以才没有更多的使用。
         12、关于lisp的函数式编程,Python中有很多内置支持,如map、zip、filter等等,当然还有lambda。不要说支持,我们谈实用。Pythoner中尚且有些人认为函数式编程影响了代码可读性而尽量避免呢。所以,你认为支持什么东西之前,先想好这样东西算不算是个好东西。
          13、"最大的不足正是因为ruby的强大所引起的"。这句真恶心,不予评论。
          14、呵呵,ruby居然没有国际化支持,真是个笑话,不知道当初那个小日本怎么想的?难道他英语过了四级?
          15、至于jython,现在也有了jruby,可能是作者的原文比较早的缘故吧。Python也有很多种实现,像是jython, 
                ironpython, pypy, 
                pyrex等等。Python的优秀其实并不一定要通过用其他语言来实现才能体现出来。当然更不要说寄希望于要Java来解救水深火热中的ruby了。
                另外么,有些ruby的缺点不要回避:
          16、ruby没有本地化线程,而是用的伪线程,根本无法利用多核CPU的优势。CPython使用了本地化线程,但是因为使用了GIL所以也是无法利用多核CPU优势的。但是Stackless的出现完全可以解决这个问题,并且stackless更是将Python提高到了并行计算的高度,这个高度的竞争对手可以是Erlang,ruby自然不必窥探。其中的超轻量线程技术可以确保一台很烂的机器上跑几十万的线程还很轻松。基于Twisted的异步编程方式也提供了一种选择。
          17、刚刚开始学Python的时候,就听说过一句“Python是主流动态语言中最慢的”,后来才知道,说那句话的人根本没把ruby放在眼里。如果把ruby也算进主流动态语言里,那么就会出现一个比Python还慢了一个多数量级的语言了。
          18、ruby流行么?是不是要走向PHP?PHP是个好东西,但是问题在于他只能作WEB编程,限制了PHP的应用范围,稍微需要系统一点的东西就要借助于C。而现在的ruby似乎也就是走着这条路。直到有一天,有人爆料"ruby是可以做客户端编程的",赢得大家一片好奇。况且现在的ROR能否取代什么还是个未知数。从Java 
           WEB开发中解救出来的人们也并不都是走向了ruby。


    四、评《选Ruby还是选Python?》

                Python和Ruby的设计哲学确实有很大的差异,这个问题,我就不评论哪个更好了,各有所爱吧。至于效率,Ruby永远不要考虑跟Python相比。Ruby是伪线程,而且根本没有利用多核CPU的可能,直接pass。而Python使用native 
                thread,仅仅由于部分模块不是threadsafe的而加入了GIL来限制应用多核CPU,而在我最近的测试中,在使用Twisted的异步线程之后,已经可以很好的利用多核CPU的计算能力了。执行效率上也不是一个数量级,自己试试就知道。

                拿Java对比Python,可见作者创造力之强悍,哈哈。开源项目是很符合达尔文的自然选择的,难道Ruby的开源项目少倒成了优点了?另外,在Python中我也没见除了WEB 
                framework之外有什么项目有太多的重复。举个例子,pypcap就已经基本淘汰了pcapy了。

                谈到资源,Ruby还有很长的路要走,所以提到双方都很强的时候,麻烦不要太并列化了。至于Java社区的人倾向于学Ruby,我个人认为只是被Java折磨惯了的开发人员目光太狭隘所致。语言是工具,面向对象也是工具,纯粹的面向对象并不见得高明到哪里去,Python也有函数式编程的支持,作者怎么没有提到。另外,Python的很多做法是以开发效率为第一目标的而不拘泥于各类形式,甚至为很多智力有限的人所广泛诟病的C++中的多继承,Python也可以支持。问题不在于支持了什么让你不喜欢的东西,而是让尽可能多的人用上他们喜欢的东西。另外,一直被Ruby开发者所认为的Python不够OO的一个例子就是取一个序列的长度,Python使用len(x)的方法。这个问题,如果Ruby开发者认为x.length就可以算是OO的话,那么Python也大可以直接使用x.__len__()来获取长度。从用方法来封装属性的Java角度讲,谁更OO一些呢,哈哈。

                Ruby是一个日本人的作品,呵呵,这个就不多说了,不喜欢日本的国人有很多,在此我仅在技术层面就可以把Ruby贬低下去,无须用非技术的东西了。

                关于Ruby on 
                rails,Ruby社区确实把几乎所有的精力都集中于此。但是这只能表现出Ruby的幼稚,事实已经证明了,ROR的很多模仿者已经推出无数的高级功能,远远超过了ROR,没有取代ROR只是出于先入为主的观念。如果现在的Ruby,突然失去了ROR又会是什么样子。至于作者提到的zend,居然用来跟ROR相比,有如以卵击石,我学过Python的2种WEB框架,平时也比较关注Python和Ruby的各种东西,但是zend这个东西,我是没有听说过的,不知是不是作者的作品,哈哈。如果一定要在WEB框架上有个较量的话,你可以用django,Quixote,mod_python之类的来比较一下。django,一个典型的ROR模仿品,还在成长,但是已经有很多优于ROR的功能了,而性能上远优于ROR自不必说。应用Quixote的douban.com是所有使用Python和Ruby网站中流量最大的,而且在相同硬件配置的情况下比ROR实现速度快了一倍还多,要知道去除WEB服务器等等的各种平等损耗之后,这可是要快上一个数量级的东西。至于mod_python,据说www.gnu.org用的就是这个。如果Ruby还想开源的话,那么就永远活在Python的阴影里面吧。

                至于上手的速度,各个人有不同的情况,不作评论。至于灵活性所带来的东西,仁者见仁,就不要评论了。作者谈到Python的入门不容易,真不知Ruby有个何等容易。我初学Python时,第11天就用Python写了一个词法解析器,至今仍然在我博客上可查。所以,入门难度这个东西,每个人还是自己去试试为好,不必听别人怎么说。

                提到ROR生成的目录有很多东西,要很久才可以都了解,这确实是IDE的综合症。在Python下,比较典型的例子是TurboGears,如果你希望了解整个应用程序的运行方式,你可以从核心cherrypy开始学习,然后开始使用TurboGears就没有什么可不了解的东西了。在这个角度上,ROR没有选择。再者,现在ROR可用的一种连接WEB服务器的方式scgi,当年也是Python的作品,又是一个在Python的阴影下活着的小东西。

                未来的发展么,孤注一掷的Ruby还很难说,但既然是孤注一掷,风险还是蛮大的。而Python么,我也以为真的会平稳的发展,但是后来Micro$oft的加入,让我们都难以预料Python的未来到底有多大了。我们再回头谈谈作者一直讨厌的Python的多样性,在我看来Ruby可以超越Python的东西屈指可数,而Python超过Ruby的东西,自然是Ruby难以逾越的鸿沟。所以从编程语言的多样性考虑,也就不建议大家学Ruby了吧,少了一种选择,聚集一些人气总是好的。


    五、python和ruby,我选谁? 
    其实python和ruby非常接近,比大多数别的语言要接近的多,所以喜欢用啥就用啥(大实话,虽然也是废话)。语法上的差别虽然有那么一点,大部分是syntax sugar,我斗胆稍微列几个(python我也忘得差不多了,不对的大家尽管来鞭尸吧),但是主要差异还是设计思想上的:灵活vs明确. 我不认为两者在生产力上会有什么差别,如果你熟悉的话。*注意,仅限语言本身的比较。

    1. ruby的case可以匹配很多东西:范围/数组,对象,正则表达,python没有case/switch而使用if/else比较死板点

    2. python的缩进很漂亮,虽然有时会造成些许麻烦。ruby的end蛮难看的,所以大家都被逼当one liner(玩笑)

    3. 感觉上ruby比python更OO,当然这也可能是因为python不提倡用那些改变对象内部构造的‘伎俩’造成的错觉

    4. python有list comprehension, ruby没有:(

    5. python有真正的keyword argument, ruby用hash模拟,当然实际用起来没什么差别

    6. python的self很讨厌,ruby没有那种繁琐的东西

    7. reflection,ruby内置了很多方法,比如object.methods,而python把这些信息存在特殊的字典里。差不多

    8. ruby的block功能很强,python的lambda只能返回单一值

    9. ruby的open class已经声明远播,可以玩出2.days.ago这样的花样,python好像没法直接修改内置类也反对这么做。

    10. python需要用@classmethod修饰声明类方法,ruby是内建

    11. ruby有单子方法,也就对对象单独定制,python不知道有没有类似概念

    12. ruby有method_missing机制,python可以使用__getattr__截获未定义方法(from qiezi)

    13. ruby使用单继承+mixin,python使用多重继承,不过python也有mixin

    14. ruby有attr_*系列语法helper,省却自己写一堆setter/getter, python的property方法还是得自己写setter/getter

    15. ruby和python都使用duck typing,不过python也有一套显式的interface机制(从zope3并入内核了么?)

    16. ruby的函数调用括号是可省的,稍微少敲几下键盘。python默认没括号也不带参数的话返回函数本身的一个引用。

    17. 我不清楚python的meta programming能到什么程度,只好等大牛来说说了。只是觉得pythoner不常用那个,也许觉得会把程序逻辑搞得晦涩不明。

    18. ruby从perl继承了一部分难看的东西,比如很多预定义的$x常量

    19. ruby内建正则表达,方便一点

    20. ruby的yield是用来call block的。而python的yield是用来给generator输入输出值的。

    21. python的库给我感觉命名规范有点不统一,有些方法用snake_case有些则用CamelCase,也许是库太多了遗留下的历史问题

    22. python的三引号很漂亮,ruby的<<-XX...XX太难看了,也可以用%q{...}包裹多行文字(from qiezi)

    23. ruby的类库设计中喜欢给方法添加别名,方便记忆。

    另: ruby官方网站也提供了一些基本的比较。

    六、两种语言的资源和学习曲线比较:

    总体的印象,用一个不大恰当的比喻:如果Python是Java,那么Ruby就是.net。我们知道,Java世界非常复杂,非常多样性,任何一个需求,都会有很多开源项目,他们用不同的思想来实现,性能特点迥异,到底选那个,总是令人犯难。现在Python也是如此,而由于Python开发难度远远低于Java,导致Python的相关项目比Java还要多得多。

    资源上,两者社区都很强,有趣的是,现在Java社区存在被Ruby同化的危险,至少我订阅的几个Java blog聚合中谈Ruby比Java还多。Ruby的社区较为集中,Python则比较分散。我总怀疑Ruby的日本用户较多,但因为不懂日文,很难确认这个想法。对于一个母语非英语的创始人,我总是有点恐惧,怕很难理解他,怕很难得到最新消息等等,虽然这个担心目前看来并无必要,不过,谁知道会怎么样呢!

    Ruby之所以现在突然变得热门,和rails这套架构是分不开的。考虑Ruby,就要考虑到Ruby on rails。rails提供了一套非常好的web开发框架,开发效率非常高。Python虽然有很多类似的架构实现,但并没有出现一个能够一统江湖的架构。Python的zend虽然完整,但更偏向于web服务器,不能用来和rails比较。

    Ruby比pyton更容易上手。从语言特征看,Ruby有很多有意思的创造,比如说block,但大规模的应用这些好玩的东西让程序变得混乱。Python语法强调简单,但是由于太灵活,简单得太过分,于是传统程序员经常会看到一些令人大吃一惊的表达方式。我不知道这应该算优点还是缺点,至少我认为语法过于灵活,容易导致不同程序员的代码风格差异过大,增加了学习成本。

    初期入门,Ruby更容易,但一旦达到一定复杂度,那么Ruby的难度骤然加大。Python入门不容易,复杂的时候也不会太痛苦。rails有入门简单,深入难的问题。rails生成的目录是做什么用途?o/r mapping如何实现的?如何把数据从web中传递到数据库的。这些都是Ruby程序员早晚要面对的问题。Python则不会这样,如果搞不清楚这些,大概根本没办法开始。集成度太高的快速开发工具都有这个特点,无论是VB、Delphi,还是.net,有多少使用了半年以内的开发人员可以说清楚工程目录下面所有的文件的用途、每个文件中的语法?我相信很多很有经验的用户也未必说的清楚。

    从架构上看,二者虽然实际上相差甚远,但最后表现出来的结果反而很相似。Ruby是纯粹的OO语言,而Python是函数和OO混合型。虽然Ruby也能用函数风格的编码方式,但实际上是模拟出来的。他们的这个差距对于普通的程序员影响并不大,毕竟看起来差不多。

    总体来说,如果是非专业人员初尝开发,Ruby是合适的。对于专业的程序员,我还是建议选择Python。

    对于未来发展,我认为Python的发展可预见,会较为平稳。Python已经属于一个社区,而非一个人,但Ruby由于种种原因,Ruby的作者maze的意志仍然会对Ruby的发展造成较大影响。Sun控制着Java,但由于sun的资源强大,且组织了jcp进行统筹,所以Java发展很不错,但Ruby能不能作到这一点,还需要时间来证明。


    七、从Python到Ruby
    Python是一门非常优秀的语言,从Python迁移到Ruby,你将发现一些语法上的不同。

     相似点

    和Python一样,在Ruby中,...

    有一个交互提示 (叫做 irb).
    你可以在命令行中读取文档 (通过ri 命令来替代 pydoc).
    没有特殊的结束一行的符号 (新行除外).
    文字可以用多行,就像Python中的三个引号.
    List用[],Dict用{} (Dict在Ruby中叫“hashes”).
    Arrays的工作方式相同(2个Array相加成为一个更加长的Array,但是想这样a3 = [ a1, a2 ] 合并,将产生一个包含数组的数组).
    Objects是有固定类型和动态转换的.
    一切都是object,变量名只是一个指向Object的指针.
    虽然关键字不同, 但是exceptions的工作方式不变.
    你拥有嵌入文档的工具 (在Ruby中叫做rdoc).
     

    不同点

    与Python不同, 在Ruby中,...

    Strings是可以改变的。
    你可以使用常量(常量的值是不同改变的)。
    这里有些强制规定的书写要求 (例如:class的名字以大写字母开头, 变量名已小写字母开头)。
    这里只有一种容器(Array), 并且是可以改变的。
    引号中的String限制不同。
    这里没有新风格的Class,Class只有一种风格。
    你无法直接访问属性,在Ruby中,都是通过方法调用实现的。
    在方法调用中使用(),是一种可选的策略。
    这里用private等等限制访问的关键字,来替代Python中的名字隐藏。
    “mixin’s”用来替代多继承。
    你可以在任何时候修改已有的Class,并添加新的方法。
    用true和false来替代True和False (用nil来替代None)。
    在判断真值的时候,只有false和nil会被认为是假.其他所有的都认为是真(包括0, 0.0, "",和[])。
    用elsif替代elif.
    用require替代import. 但是用法是相同的。
    用usual-style来注释文档(替代docstrings) 同时用来生成文档。
     

    八、从三个方面来进行Python和Ruby的比较:

    1.各自所适用于什么应用
    2.开发环境、运行环境
    3.可移植性如何,因为项目最后计划移植到手机平台,如windows CE Symbina


    【1.各自所适用于的应用场合】

    查阅的结果似乎对于这两种语言的评价都很好,在网络开发上的性能都很好。都很适用于快速的应用程序开发,开发的效率很高。

    Python:

    摘取了跟项目有关的一些应用方面的叙述

    跨平台开发:

    Python 以中立方式支持不同的一系列平台,如果用户使用的系统包含不同的平台,使用 Python 开发应用程序则再好不过;它这种适应性也可以为系统预留使用其它工具的可能。对于频繁更换平台用户,Python 是个理想的选择。
    为最终用户提供软件服务时,Python 也是个备选方案,可以避免同时用不同应用软件编程的时间和费用。

    互联网程序设计:

    Python 带有的标准模块可以对网络插槽进行初级和协议级别的通讯,比如,如果要从 POP 服务器上读取电子邮件,Python 随带的库模块可以做到。另外, Python 还支持 XML、HTML和 CGI 库文件,所以利用它可以解析用户输入的需求,并通过网络服务器产生最佳质量的成果。
    程序员还可为拥有 Python 内置解释器的 Apache、Unix 和 Windows 网络服务器编译模块。基于 CGI 程序的功效,可以很方便地执行 Python 语句而不用单独装载。 
    针对于python的网络编程,有一本很好的书:《python网络编程基础》
    这本书全面介绍了使用Python语言进行网络编程的基础知识,主要内容包括网络基础知识、高级网络操作、Web Services、解析HTML和XHTML、XML、E-mail服务、FTP、使用Python操作数据库、SSL、几种服务器端框架(包括Socket服务器、SimpleXMLRPCServer、CGI和mod_python),以及多任务处理(包括Forking、线程和异步通信)等。本书实用性强,共提供了大约175个实例,6600行以上的代码,是帮助读者全面而快速地学习Python语言、编写网络程序的最佳实践。


    Ruby:

    功能强大,面向对象的脚本语言,可以使您方便快捷地进行面向对象编程,有时使用像Smalltalk、Eiffel或C++这样正式的面向对象语言来开发一些小项目显得有点"小题大做",而Ruby刚好可以满足这些面向对象编程的需求.当然了,您也可以使用Ruby进行普通的面向过程编程。
    Ruby支持很多网络协议,不管是高层的还是底层的。ruby提供了一些基本类,让你可以使用TCP,UDP,SOCKS等很多协议交互,而不必拘泥在网络层。这些类也提供了辅助类,让你可以轻松的对服务器进行读写。进行网络编程也是很不错。


    【2.开发环境、运行环境】

    Python:

    相比之下,就是没有一个很强的集成开发环境。有人说开源软件相对于收费的那种软件好用一些。
    用得较多的几个:
    Python自带的idle:
    不是python的IDE中最好的……
    PythonWin :

    使用起来非常得心应手(就像使用 Windows 那样舒服)。它有个好用的编辑器,包括代码合并、语法标签高亮显示以及代码自动完成特性。PythonWin 和有些 IDE 一样,不包含任何类型的表单设计器;但它提供一个优秀的调试器,具有监视、代码检查、交互调试窗口、断点、和其他调试器该有的功能。最重要的是,PythonWin 很稳定,尽管有时候在 Win95r2 系统上使用时会奇怪地“停止响应”。界面上来说,PythonWin 比较简单,但非常吸引人,很好的运用了可嵌入和可对接的元素(我有点偏爱 Idle 风格的 "many windows everywhere",它也为其他许多 IDE 所采用的)。PythonWin 还集成了 ActiveState 的 HtmlHelp 版本的 Python 说明文档和 PythonCOM。

    eclipse的pydev插件,eclipse+pydev
    Pydev 基于Eclipse的,非常棒的Python环境,改进速度非常快。提供的一些功能

    UliPad :
    一个编辑器,你可以用它来进行你的文档写作,编程开发。它使用 Python 编程语言开发,用户界面基于 wxPython 。它除了想要完成一般编辑器的常用功能之外,最主要是想实现一种方便、灵活的框架,开发者可以方便地开发新的功能。而且有编程经验的用户还可以针对日常工作中的特别问题编制处理的插件,从而使之与自已的日常工作紧密结合起来。由于使用的是 Python 这种功能强大的编程语言,你可以方便地对本软件进行修改,从而满足自已的需要。
    UliPad 支持代码着色、智能补全、代码调试、Python类浏览、代码片段、Ftp功能、目录浏览等等强大功能,其 Doc 目录下的文档更是非常丰富,是你编写 Python 的绝世好帮手!
    系统要求:
    python 2.4+
    wxPython 2.6+

    我们最后选择的是UliPad,还是挺棒的。

     

    Ruby:

    Ruby有极好的高级调试器。

    可以用netbeans的ruby插件或eclipse的ruby插件

    Eclipse下安装开发环境的大致过程:
    1. 安装 Ruby 1.8.6 One-Click Installer。
    2. 将 Eclipse Platform Runtime Binary 压缩包解压到某个目录。
    3. 将 Ruby Development Tools 压缩包的内容解压缩到 Eclipse 相应目录下。

    运行环境在其官方网站上下载相应的版本再安装即可,windows下面的安装较为简单,双击运行即可安装。


    【3.可移植性】

    Python:

    由于它的开源本质,Python已经被移植在许多平台上(经过改动使它能够工作在不同平台上)。如果你小心地避免使用依赖于系统的特性,那么你的所有Python程序无需修改就可以在下述任何平台上面运行。这些平台包括Linux、Windows、FreeBSD、Macintosh、Solaris、OS/2、Amiga、AROS、AS/400、BeOS、OS/390、z/OS、Palm OS、QNX、VMS、Psion、Acom RISC OS、VxWorks、PlayStation、Sharp Zaurus、Windows CE甚至还有PocketPC!

    Python在执行时,首先会将.py文件中的源代码编译成Python的byte code(字节码),然后再由Python Virtual Machine来执行这些编译好的byte code。这种机制的基本思想跟Java,.NET是一致的。然而,Python Virtual Machine与Java或.NET的Virtual Machine不同的是,Python的Virtual Machine是一种更高级的Virtual Machine。这里的高级并不是通常意义上的高级,不是说Python的Virtual Machine比Java或.NET的功能更强大,而是说和Java 或.NET相比,Python的Virtual Machine距离真实机器的距离更远。或者可以这么说,Python的Virtual Machine是一种抽象层次更高的Virtual Machine。

    可以安装一种面向对象的解释性的计算机程序设计语言,也是一种功能强大而完善的通用型语言,已经具有十多年的发展历史,成熟且稳定。Python 具有脚本语言中最丰富和强大的类库,足以支持绝大多数日常应用.在Symbina智能手机上支持C++和JAVA开发的两类程序,装上Python后,也就可以支持众多以Python开发的各种程序了。对于普通的手机用户,我们不用了解太多,只是安上Python这个平台就可以了,可以让我们的手机支持更多以Python开发的程序。目前在Symbian手机上已经有相当多的Python开发的程序,也都是比较实用的。


    Ruby:

    它大部分是在Linux上开发的,但是可以在很多类型的Unix, Dos, Windows95/98/Me/NT/2000/XP, MacOS, BeOS, OS/2等系统上运行。
    关于ruby跟手机开发的资料很少,有在windows CE上运行的版本,但是好像现在相关的资料还特别少,而且安装失败、编译不通过的例子偏多。日文页面上有少量的日文介绍。


    【总结】
    然后针对于Python跟Ruby在朋友的建议下还给出了如下一些参考意见,在此感谢他:

    1.  Python也被称为是一门清晰的语言。因为它的作者在设计它的时候,总的指导思想是,对于一个特定的问题,只要有一种最好的方法来解决就好了。Python语言是一种清晰的语言的另一个意思是,它的作者有意的设计限制性很强的语法,使得不好的编程习惯(例如if语句的下一行不向右缩进)都不能通过编译。这样有意的强制程序员养成良好的编程习惯。Python在其他部分的设计上也坚持了清晰划一的风格,这使得Python称为一门易读性、易维护性好,并且被大量用户所欢迎的、用途广泛的语言。
    同一个问题用Python几个人分别写写出来的代码会很相近。但Ruby则设计思想不一样,用它写出来的程序太过于灵活,不同的人写出来可能相差会很大。

    2.  Ruby英文文档极度缺乏,中文文档就更不用说。Python社区相对成熟,也有一大堆的资料。

     

    最后给出Python的几个网站

    1. http://www.python.org/ - Python 的官方网站 
    2. http://python.cn/ - Python 中文社区 
    3. http://www.codeplex.com/Wiki/View.aspx?ProjectName=IronPython Python For Dot Net 的网站

    Ruby的几个网站
    1、www.ruby-lang.org/zh_CN  Ruby中文官方网站
    2、http://www.rubystudy.com/bbs/tag.php?name=Ruby  Ruby中文学习交流社区
    3、http://ruby-lang.guo.cc/  Ruby在线参考手册

    展开全文
  • Ruby on Rails入门

    千人学习 2018-12-04 13:43:52
    Ruby 是最优雅的开发语言,Rails是Web开发最快的框架。Ruby on Rails是目前美国创业公司最喜欢用的技术,开发效率基本上是传统Web开发框架的3-5倍。 本视频介绍了Ruby on Rails的快速入门的路径, 可以让新手快速...
  • Ruby语言简介

    千次阅读 2019-09-04 16:40:28
    Ruby是一种解释型、面向对象、动态类型的语言。Ruby采取的策略是在灵活性和运行时安全之间寻找平衡点。随着Rails框架的出现,Ruby也在2006年前后一鸣惊人,同时也指引人们重新找回编程乐趣。尽管从执行速度上说,...

    Ruby是一种解释型、面向对象、动态类型的语言。Ruby采取的策略是在灵活性和运行时安全之间寻找平衡点。随着Rails框架的出现,Ruby也在2006年前后一鸣惊人,同时也指引人们重新找回编程乐趣。尽管从执行速度上说,Ruby谈不上有多高效,但它却能让程序员的编程效率大幅提高。本文将讲述Ruby语言的基础语言特性,包括基本的语法及代码块和类的定义。

     

    1. 基础
    在Ruby交互命令行中输入以下命令(>>为命令行提示符,=>为返回值;下文将把=>符号和语句写在一行内表明其返回值):

    >> puts 'hello, world'
    hello, world
    => nil
    
    >> language = 'Ruby'
    => "Ruby"
    
    >> puts "hello, #{language}"
    hello, Ruby
    => nil

    以上代码使用puts输出,给变量赋值,并用#{}的语法实现字符串替换。这表明Ruby是解释执行的;变量无需声明即可直接初始化和赋值;每条Ruby代码都会返回某个值;单引号包含的字符串表示它将直接被解释,双引号包含的字符串会引发字符串替换。

    1.1 编程模型

    Ruby是一门纯面向对象语言,在Ruby中一切皆为对象,可以用“.”调用对象具有的方法,可以通过class和methods方法查看对象的类型及支持的方法,如4.class => Fixnum,7.methods => ["inspect", "%", "<<", "numerator", ...],false.class => FalseClass(方括号表示数组)。

    1.2 流程控制

    条件判断有正常的块形式,也有简单明了的单行形式;除了常见的if语句外,还有unless语句(等价于if not,但可读性更强)。同理,循环也有正常的块形式和单行形式。注意:除了nil和false之外,其他值都代表true,包括0!

    # 块形式
    if x == 4
     puts 'This is 4.'
    end
    # 单行形式
    puts 'This is false.' unless true
    x = x + 1 while x < 10 # x的结果为10
    x = x - 1 until x == 1 # x的结果为1

    和其他C家族的语言差不多,Ruby的逻辑运算符and(&&)、or(||)都自带短路功能,若想执行整个表达式,可以用&或|

    1.3 鸭子类型

    执行4 + 'four'会出现TypeError的错误,说明Ruby是强类型语言,在发生类型冲突时,将得到一个错误。如果把个语句放在def...end函数定义中,则只有在调用函数时才会报错,说明Ruby在运行时而非编译时进行类型检查,这称为动态类型。Ruby的类型系统有自己的潜在优势,即多个类不必继承自相同的父类就能以“多态”的方式使用:

    a = ['100', 100.0]
    puts a[0].to_i # => 100
    puts a[1].to_i # => 100

    这就是所谓的“鸭子类型”(duck typing)。数组的第一个元素是String类型,第二个元素是Float类型,但转换成整数用的都是to_i。鸭子类型并不在乎其内在类型是什么,只要一个对象像鸭子一样走路,像鸭子一样嘎嘎叫,那它就是只鸭子。在面向对象设计思想中,有一个重要原则:对接口编码,不对实现编码。如果利用鸭子类型,实现这一原则只需极少的额外工作,就能轻松完成。

    1.4 函数

    def tell_the_truth
     true
    end

    每个函数都会返回结果,如果没有显式指定返回值,函数就将退出函数前最后处理的表达式的值返回。函数也是个对象,可以作为参数传给其他函数。

    1.5 数组

    和Python一样,Ruby的数组也是用中括号来定义,如animals = ['lion', 'tiger', 'bear'];负数下标可以返回倒数的元素,如animals[-1] => "bear";通过指定一个Range对象来获取一个区段的元素,如animals[1..2] => ['tiger', 'bear']。此外,数组元素可以互不相同,多为数组也不过是数组的数组。数组拥有极其丰富的API,可用其实现队列、链表、栈、集合等等。

    1.6 散列表

    numbers = {2 => 'two', 5 => 'five'}
    stuff = {:array => [1, 2, 3], :string => 'Hi, mom!'}
    # stuff[:string] => "Hi, mom!"

    散列表可以带任何类型的键,上述代码的stuff的键较为特殊——它是一个符号(symbol),前面带有冒号标识符。符号在给事物和概念命名时很好用,例如两个同值字符串在物理上不同,但相同的符号却是同一物理对象,可以通过反复调用'i am string'.object_id和:symbol.object_id来观察。另外,当散列表用作函数最后一个参数时,大括号可有可无,如tell_the_truth :profession => :lawyer。

     

    2. 面向对象
    2.1 代码块

    代码块是没有名字的函数(匿名函数),可以用作参数传递给函数。代码块只占一行时用大括号包起来,占多行是用do/end包起来,可以带若干个参数。

    3.times {puts 'hehe'} # 输出3行hehe
    ['lion', 'tiger', 'bear'].each {|animal| puts animal} # 输出列表的内容

    上面的times实际上是Fixnum类型的方法,要自己实现这样一个方法非常容易:

    class Fixnum
     def my_times
      i = self
       while i > 0
        i = i - 1
        yield
      end
     end
    end
    3.my_times {puts 'hehe'} # 输出3行hehe
    

    这段代码打开一个现有的类,向其中添加一个自定义的my_times方法,并用yield调用代码块。在Ruby中,代码块不仅可用于循环,还可用于延迟执行,即代码块中的行为只有等到调用相关的yield时才会执行。代码块充斥于Ruby的各种库,小到文件的每一行,大到在集合上进行各种复杂操作,都是由代码块来完成的。

    2.2 类

    调用一个对象的class方法可以查看其类型,调用superclass可以查看这个类型的父类。下图展示了数字的继承链,其中横向箭头表示右边是左边实例化的对象,纵向箭头表示下边继承于上边。Ruby的一切事物都有一个共同的祖先Object。

     

    最后通过一个完整的实例——定义一棵树,来看下Ruby的类如何定义和使用,该注意的点都写在注释里面了。

    class Tree
     # 定义实例变量,使用attr或attr_accessor关键字,前者定义变量和访问变量的同名getter方法(即只读),后者定义的变量多了同名setter方法(注意这里使用了符号)
     attr_accessor :children, :node_name
    
     # 构造方法(构造方法必须命名为initialize)
     def initialize(name, children=[])
      @node_name = name
      @children = children
     end
    
     # 遍历所有节点并执行代码块block,注意参数前加一个&表示将代码块作为闭包传递给函数
     def visit_all(&block)
      visit &block
      children.each {|c| c.visit_all &block}
     end
    
     # 访问一个节点并执行代码块block
     def visit(&block)
      block.call self
     end
    end
    
    ruby_tree = Tree.new("Ruby", 
     [Tree.new("Reia"),
      Tree.new("MacRuby")])
    # 访问一个节点
    ruby_tree.visit {|node| puts node.node_name}
    # 访问整棵树
    ruby_tree.visit_all {|node| puts "Node: #{node.node_name}"}

    再提一下Ruby的命名规范:

    (1)类采用CamelCase命名法
    (2)实例变量(一个对象有一个值)前必须加上@,类变量(一个类有一个值)前必须加上@@
    (3)变量和方法名全小写用下划线命名法,如underscore_style
    (4)常量采用全大写下划线命名法,如ALL_CAPS_STYLE
    (5)用于逻辑测试的函数和方法一般要加上问号,如if test?

     

    3. 模块与混入(Mixin)
    面向对象语言利用继承,将行为传播到相似的对象上。若一个对象像继承多种行为,一种做法是用多继承,如C++;Java采用接口解决这一问题,Ruby采用模块Mixin。模块是函数和常量的集合,若在类中包含一个模块,那么该模块的行为和常量也会成为类的一部分。

    # 定义模块ToFile
    module ToFile
     # 获取文件名
     def filename
      "object_name.txt"
     end
    
     # 创建文件
     def to_f
      File.open(filename, 'w') {|f| f.write(to_s)} # 注意这里to_s在其他地方定义!
     end
    end
    
    # 定义用户类
    class Person
     include ToFile
     attr_accessor :name
    
     def initialize(name)
      @name = name
     end
    
     def to_s
      name
     end
    end
    
    Person.new('matz').to_f # 创建了一个文件object_name.txt,里面包含内容matz

    上面的代码很好理解,只是有一点要注意:to_s在模块中使用,在类中实现,但定义模块的时候,实现它的类甚至还没有定义。这正是鸭子类型的精髓所在。写入文件的能力,和Person这个类没有一点关系(一个类就应该做属于它自己的事情),但实际开发又需要把Person类写入文件这种额外功能,这时候mixin就可以轻松胜任这种要求。

    Ruby有两个重要的mixin:枚举(enumerable)和比较(comparable)。若想让类可枚举,必须实现each方法;若想让类可比较,必须实现<=>(太空船)操作符(比较a,b两操作数,返回1、0或-1)。Ruby的字符串可以这样比较:'begin' <=> 'end => -1。数组有很多好用的方法:

    a = [5, 3, 4, 1]
    a.sort => [1, 3, 4, 5] # 整数已通过Fixnum类实现太空船操作符,因此可比较可排序
    a.any? {|i| i > 4} => true
    a.all? {|i| i > 0} => true
    a.collect {|i| i * 2} => [10, 6, 8, 2]
    a.select {|i| i % 2 == 0} => [4]
    a.member?(2) => false
    a.inject {|product, i| product * i} => 60 # 第一个参数是代码块上一次执行的结果,若不设初始值,则使用列表第一个值作为初始值

     

    4. 元编程(metaprogramming)
    所谓元编程,说白了就是“写能写程序的程序”,这说起来有点拗口,下面会通过实例来讲解。

    4.1 开放类

    可以重定义Ruby中的任何类,并给它们扩充任何你想要的方法,甚至能让Ruby完全瘫痪,比如重定义Class.new方法。对于开发类来说,这种权衡主要考虑了自由,有这种重定义任何类或对象的自由,就能写出即为通俗易懂的代码,但也要明白,自由越大、能力越强,担负的责任也越重。

    class Numeric
     def inches
      self
     end
     def feet
      self * 12.inches
     end
     def miles
      self * 5280.feet
     end
     def back
      self * -1
     end
     def forward
      self
     end
    end

    上面的代码通过开放Numeric类,就可以像这样采用最简单的语法实现用英寸表示距离:puts 10.miles.back,puts 2.feet.forward。

    4.2 使用method_missing

    Ruby找不到某个方法时,会调用一个特殊的回调方法method_missing显示诊断信息。通过覆盖这个特殊方法,可以实现一些非常有趣且强大的功能。下面这个示例展示了如何用简洁的语法来实现罗马数字。

    class Roman
     # 覆盖self.method_missing方法
     def self.method_missing name, *args
      roman = name.to_s
      roman.gsub!("IV", "IIII")
      roman.gsub!("IX", "VIIII")
      roman.gsub!("XL", "XXXX")
      roman.gsub!("XC", "LXXXX")
    
      (roman.count("I") +
       roman.count("V") * 5 +
       roman.count("X") * 10 +
       roman.count("L") * 50 +
       roman.count("C") * 100)
     end
    end
    
    puts Roman.III # => 3
    puts Roman.XII # => 12

    我们没有给Roman类定义什么实际的方法,但已经可以Roman类来表示任何罗马数字!其原理就是在没有找到定义方法时,把方法名称和参数传给method_missing执行。首先调用to_s把方法名转为字符串,然后将罗马数字“左减”特殊形式转换为“右加”形式(更容易计数),最后统计各个符号的个数和加权。

    当然,如此强有力的工具也有其代价:类调试起来会更加困难,因为Ruby再也不会告诉你找不到某个方法。因此method_missing是一把双刃剑,它确实可以让语法大大简化,但是要以人为地加强程序的健壮性为前提。

    4.3 使用模块

    Ruby最流行的元编程方式,非模块莫属。下面的代码讲述如何用模块的方式扩展一个可以读取csv文件的类。

    module ActsAsCsv
    
     # 只要某个模块被另一模块include,就会调用被include模块的included方法
     def self.included(base)
      base.extend ClassMethods
     end
    
     module ClassMethods
      def acts_as_csv
       include InstanceMethods
      end
     end
    
     module InstanceMethods
      attr_accessor :headers, :csv_contents
    
      def initialize
       read
      end
    
      def read
       @csv_contents = []
       filename = self.class.to_s.downcase + '.txt'
       file = File.new(filename)
       @headers = file.gets.chomp.split(', ') # String的chomp方法去除字符串末尾的回车换行符
       file.each do |row|
        @csv_contents << row.chomp.split(', ')
       end
      end
     end
    
    end # end of module ActsAsCsv
    
    class RubyCsv  # 没有继承,可以自由添加
     include ActsAsCsv
     acts_as_csv
    end
    
    m = RubyCsv.new
    puts m.headers.inspect
    puts m.csv_contents.inspect

    上述代码中RubyCsv包含了ActsAsCsv,所以ActsAsCsv的included方法中,base就指RubyCsv,ActsAsCsv模块给RubyCsv类添加了唯一一个类方法acts_as_csv,这个方法又打开RubyCsv类,并在类中包含了所有实例方法。如此这般,就写了一个会写程序的程序(通过模块来动态添加类方法)。

    一些出色的Ruby框架,如Builder和ActiveRecord,都会为了改善可读性而特别依赖元编程。借助元编程的威力,可以做到尽量缩短正确的Ruby语法与日常用于之间的距离。注意一切都是为了提升代码可读性而服务。

     

    5. 总结
    Ruby的纯面向对象可以让你用一致的方式来处理对象。鸭子类型根据对象可提供的方法,而不是对象的继承层次,实现了更切合实际的多态设计。Ruby的模块和开放类,使程序员能把行为紧密结合到语法上,大大超越了类中定义的传统方法和实例变量。
    核心优势:
    (1)优雅的语法和强大的灵活性
    (2)脚本:Ruby是一门梦幻般的脚本语言,可以出色地完成许多任务。Ruby许多语法糖可以大幅提高生产效率,各种各样的库和gem(Ruby包)可以满足绝大多数日常需要。
    (3)Web开发:很多人学Ruby最终就是为了用Ruby on Rails框架来进行Web开发。作为一个极其成功的MVC框架,其有着广泛的社区支持及优雅的语法。Twitter最初就是用Ruby实现的,借助Ruby无比强大的生产力,可以快速地开发出一个可推向市场的合格产品。
    不足之处:
    (1)性能:这是Ruby的最大弱点。随着时代的发展,Ruby的速度确实是越来越快。当然,Ruby是创建目的为了改善程序员的体验,在对性能要求不高的应用场景下,性能换来生产效率的大幅提升无疑是值得的。
    (2)并发和面向对象编程:面向对象是建立在状态包装一系列行为的基础上,但通常状态是会改变的。程序中存在并发时,这种编程策略就会引发严重问题。
    (3)类型安全:静态类型可提供一整套工具,可以更轻松地构造语法树,也因此能实现各种IDE。对Ruby这种动态类型语言来说,实现IDE就困难得多。

     

    展开全文
  • 理性分析Python和Ruby哪个更有前途?

    万次阅读 2018-06-19 16:54:45
    就第一语言而言,Ruby和Python是最受欢迎的。Ruby是非常流行的构建网站技术,其中最著名的是Twitter(早期版本),Basecamp,Github,Airbnb,Slideshare,Groupon。Ruby和Python都是面向对象的语言,都是动态和灵活的。这些...

    就第一语言而言,Ruby和Python是最受欢迎的。Ruby是非常流行的构建网站技术,其中最著名的是Twitter(早期版本),Basecamp,Github,Airbnb,Slideshare,Groupon。

    Ruby和Python都是面向对象的语言,都是动态和灵活的。这些技术的主要区别在于他们解决问题的方式。Ruby提供了不同的方法,而Python通常只有一个。这个事实既是优势也劣势。

    最流行的Ruby框架是Ruby on rails。它和Django非常类似,因为这两个框架都是为了解决相同的任务。如果我们比较这些技术的社区,我们会发现他们几乎是一样的,然而,形成这些团体的人是不同的。Python在数据科学和数学方面很受欢迎,所以在这里你可以找到很多的学者和教授。

    记住,当你开发web应用程序时,可以用RoR实现,也可以用Django,两者都是快速高效的。如果开发偏重于大量计算和数据处理的应用,应该选择Python。

    任何技术成功的秘密在于围绕它所构建的社区,不同人群协同工作来确定其未来的发展演变,Python的支持者是世界上规模最大和构成最多样化的一个团队,不仅有数以千计的个人开发者,而且还有诸如谷歌,Yandex,Dropbox,Mozilla,微软(在Visual Studio中使用),英特尔等许多巨头公司,他们和其他许多公司一起,已经用Python创建了世界上最大的和最受欢迎的项目。

    与Ruby相比,Python更加流行,目前已广泛应用于人工智能、云计算开发、大数据开发、数据分析、科学运算、网站开发、爬虫、自动化运维、自动化测试、游戏开发等领域,就业范围广,薪资相对较高,且入门简单,很适合初学者学习!


    展开全文
  • ruby2.6.1.zip

    2020-07-30 23:33:20
    Ruby是一种面向对象的脚本语言,目前最新的版本是ruby2.6.1,官网国内基本很难下载,这里转存下!该版本是zip版,解压即可使用,无需安装。
  • ruby中=>是什么意思

    千次阅读 2019-06-19 20:41:06
    如果是对数组赋值,下标 => 值例如 a = {1 => "1",2 => "22"}a[1] "1"a[2] "22" 转载于:https://www.cnblogs.com/fpcbk/p/10824222.html
  • ruby1.9.3下载

    2020-07-30 23:32:19
    ruby1.9.3版本
  • Ruby是什么

    千次阅读 2019-01-24 10:55:17
    Ruby是什么
  • Ruby on Rails 是一个可以使你开发,部署,维护 web 应用程序变得简单的框架。2015年10月编程语言排行榜 Ruby进入TIOBE排行榜前十,可见其流行程序如此之高。本文就帮你打开Ruby on Rails Web开发的大门,助你进入...
  • Mac上更新Ruby

    万次阅读 2013-06-27 22:03:57
    因为准备在项目中使用bootstrap,在安装bootstrap过程中提示需要Ruby的版本在1.9.2以上,而目前使用的Ruby版本是Mac系统自带的1.8.7。所以需要对Ruby进行升级。这里使用RVM对Ruby进行升级,升级过程如下: 1、安装 ...
  • Mac下升级ruby至最新版本

    万次阅读 2016-10-22 16:10:43
    升级rubyMac OS自身安装的有ruby,但是版本较低,为2.0.x 而安装CocoaPods,最低版本是2.2查看ruby版本ruby --version安装homebrewruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)...
  • Ubuntu系统安装Ruby的三种方法

    万次阅读 2015-01-06 17:56:48
    Ubuntu系统安装Ruby的三种方法作者:chszs,转载需注明。博客主页:http://blog.csdn.net/chszsRuby是一个开源的动态编程语言,它有优美的语法,可用于构建可伸缩的Web应用程序。ruby gems可以很好地增强Ruby开发者...
  • linux CentOS7 下 ruby 卸载 | 安装

    万次阅读 2018-06-28 10:03:05
    在centos7中默认ruby是2.0.0版本,低于redis4.0.6最低的最低要求的2.2版本,所以需要进行升级。 #我的升级办法是将自带的ruby卸载,在安装可以支持redis的版本。 #卸载ruby $ yum remove ruby #下载 $ wget phttps...
  • 有时候在ruby下使用gem安装包的时候,会报错如下:  ERROR: Error installing bluecloth:  ERROR: Failed to build gem native extension.   /System/Library/Frameworks/Ruby.framework/Versions/2.1/usr/...
  • mac 升级ruby版本

    万次阅读 2018-03-01 16:17:30
    使用RVM也就是Ruby Version Manager,Ruby版本管理器来升级ruby,rvm包含了Ruby的版本管理和Gem库管理(gemset)1、Rvm安装curl -L get.rvm.io | bash -s stable但执行这个语句的会出现下面错误,如图所示* WARNING:...
  • Centos7安装升级Ruby

    万次阅读 2018-09-15 20:58:32
    在做redis集群时,所需要的使用ruby工具进行操作,发现在线安装的Ruby版本过低,redis支持的版本最少为2.2.2.   在线安装ruby  使用yum在线安装ruby,安装的版本为2.0.0。 yum install ruby ruby -v ...
  • 2. Ruby下载安装

    千次阅读 多人点赞 2018-06-29 23:07:12
    如果你使用的是Mac os x,那么系统默认就安装了Ruby的,但是如果你的操作系统是Windows,那么需要自己下载安装Ruby,你可以通过Ruby的官网下载到Rubyhttp://www.ruby-lang.org/en/downloads/Ruby on Windows下载:....
  • 在linux(我用ubuntu)下,明明安装好了ruby,输入命令行ruby后,却提示 -bash: /usr/bin/ruby: No such file or directory 解决问题之前,先确认一个情况,输入命令 /usr/local/bin/ruby --version 如果有...
  • 如何安装Ruby和RubyGems

    万次阅读 2012-11-27 11:07:07
    如何安装Ruby和RubyGems 以下各节提供在Windows和Linux计算机上安装Ruby和RubyGems的各种基本信息。 Windows 下载并安装Ruby Installer for Windows.安装程序已经包含了RubyGems。 请确保当你安装和使用...
1 2 3 4 5 ... 20
收藏数 253,402
精华内容 101,360
关键字:

ruby