一、比较语句

大部分和其他的语言一样,这里注意<=>、

条件语句

如下几种形式

  • if
  • if ..else.. end
  • if..elsif..else..end
  • unless(if not)
  • case..when
  • z

注意在ruby中只有nil和false为假。

  1. x=1
  2. if x==1
  3. puts 1
  4. elsif x==2
  5. puts 2
  6. else
  7. puts 3
  8. end

注意是elsif,不是elseif。与c相比,多了个end

但Ruby的case语句和C/C++的格式差异很大:

  1. case 被判断项
  2. when 比较值 then 代码
  3. when 比较值 then 代码
  4. else 代码
  5. end
  1. def [](index)
  2. case index
  3. when 0, -2 then @x
  4. when 1,-1 then @y
  5. when :x,"x" then @x
  6. when :y,"y" then @y
  7. else nil
  8. end
  9. end

p[0],p[-2]都返回x

例如,下面两段代码是等价的,但使用case的代码更加清晰:

  1. if var < 60
  2. print "failed/n"
  3. elsif var < 70
  4. print "passed/n"
  5. elsif var < 80
  6. print "good/n"
  7. elsif var < 90
  8. print "great/n"
  9. else
  10. print "excellent/n"
  11. end
  12. case var
  13. when 0..59 then print "failed/n"
  14. when 60..69 then print "passed/n"
  15. when 70..79 then print "good/n"
  16. when 80..89 then print "great/n"
  17. else print "excellent/n"
  18. end
  1. case具有两种形式,下面的是一种,
  2. name =case
  3. when x== then "one"
  4. when x== then "two"
  5. else "many"
  6. end
  7. puts name
  8. 你可以用一个换行符或分号(分号ruby1.9不适用)替代那个跟在when从句后面的关键字when:
  9. name =case
  10. when x==
  11. "one"
  12. when x==
  13. "two"
  14. else "many"
  15. end
  16. puts name

case语句中的else从句是可选的,如果没有为true的when从句,而且存在一个else从句,那么位于else和end之间的代码将被执行。这块代码中最后执行的表达式的值将被作为整个case语句的值。如果没有为true的when从句,而且没有else从句,那么就不会执行任何代码,而且case语句的返回值为nil。

case 语句中的一个when从句可以包含多个表达式(用逗号分隔),只要有一个为true就会执行。在简单形式的case语句中,逗号作用不大,就好像一个||操作符一样:
case
when x == 1, y == 0 then "x is one or y is zero" # Obscure syntax
when x == 2 || y == 1 then "x is two or y is one" # Easier to understand
end

目前为止,展示的case比较简单,实际上case的功能比这个强大的多。在大部分例子中,每个when从句的左侧都是一样的。在case的常用形式里,我们将这些when从句的左侧提取出来,与case本身关联在一起:

  1. name = case x
  2. when 1 #just the value compare to x
  3. "one"
  4. when 2 then "two"
  5. when 3; "three"
  6. else "many"
  7. end
  8. puts name

理解case语句重点在于,搞清楚when从句的值如何与case关键字后的表达式的值相比较的。这个比较使用的是===操作符。
===是条件相等性操作符(case equality)。对于许多类来说,比如先前提到的fixnum类,===操作符的行为是和==是一样的。但某些特定的类也重定义了该方法,用于实现一些有趣的行为:Class类将===定义为测试其右侧操作数是否为左侧操作数所命名的类的一个实例;Range类将===定义为测试其右侧操作数是否位于左侧操作数的范围之内。Regexp类将测试是否为匹配指定的模式。在Ruby1。9里,Symbol类将===定义为测试符号或字符串的相等性。基于这些对条件相等性操作符的定义,我们可以编写一个下面比较有趣的case语句:

  1. puts case x
  2. when String then "string"
  3. when Numeric then "numeber"
  4. when TrueClass,FalseClass then "boolean"
  5. else "other"
  6. end
  1. # Compute 2006 U.S. income tax using case and Range objects
  2. tax = case income
  3. when 0..7550
  4. income * 0.1
  5. when 7550..30650
  6. 755 + (income-7550)*0.15
  7. when 30650..74200
  8. 4220 + (income-30655)*0.25
  9. when 74200..154800
  10. 15107.5 + (income-74201)*0.28
  11. when 154800..336550
  12. 37675.5 + (income-154800)*0.33
  13. else
  14. 97653 + (income-336550)*0.35
  15. end
  1. # Get user's input and process it, ignoring comments and exiting
  2. # when the user enters the word "quit"
  3. while line=gets.chomp do # Loop, asking the user for input each time
  4. case line
  5. when /^\s*#/ # If input looks like a comment...
  6. next # skip to the next line.
  7. when /^quit$/i # If input is "quit" (case insensitive)...
  8. break # exit the loop.
  9. else # Otherwise...
  10. puts line.reverse # reverse the user's input and print it.
  11. end
  12. end

A when clause can have more than one expression associated with it. Multiple expressions
are separated by commas, and the === operator is invoked on each one. That is,
it is possible to trigger the same block of code with more than one value:

  1. def hasValue?(x) # Define a method named hasValue?
  2. case x # Multiway conditional based on value of x
  3. when nil, [], "", 0 # if nil===x || []===x || ""===x || 0===x then
  4. false # method return value is false
  5. else # Otherwise
  6. true # method return value is true
  7. end
  8. end

case与c++中switch区别:
c++中switch可以穿越多个后续的case从句不断执行,直到到达switch语句的末尾,或者遇到一个break或return语句才会结束。ruby的case语句不允许穿越的。
在java和c等编译性语言中,与每个case标签相关联的表达式必须是编译时常量,而不能是任意的运行时表达式,这常常使编译器能够用一个非常快速的查询表(lookup table)来实现switch语句,在ruby中没有这样的限制,case语句的性能相当于一个具有多个elsif从句的if语句的性能。

三元操作符

  1. def how_many_messages(n) #handle singular/plural
  2. "you have" + n.to_s + (n==1 ? " message. " : " messages. ")
  3. end
  4. how_many_messages 1

注意:

  1. "you have" + n.to_s +(n==1 ? " message. " : " messages. ")

画红线的地方要有空格,否则错误:

F:/ruby/rubySource/ControllStrutrue.rb:44: warning: ambiguous first argument; put parentheses or even spaces
F:/ruby/rubySource/ControllStrutrue.rb:44: syntax error, unexpected tUPLUS, expecting keyword_end
"you have" + n.to_s +(n==1 ? " message. " : " messages. ")

循环迭代语句

x.times

x.updo,x.downto,x.step(limit,steplength)

在大多数语言里,if条件式是一个语句,但在ruby中,一切都是表达式,包括哪些通常被称为语句的控制结构。一个if语句的返回值就是被执行的代码中最后一个表达式的值;如果没有执行任何代码,那么返回值就是nil。

作为if语句能返回一个值的例子,我们可以优雅地将前面提到的多路条件式写成这样:

name = if x == 1 then "one"
elsif x == 2 then "two"
elsif x == 3 then "three"
elsif x == 4 then "four"
else "many"
end
puts name

unless和if相反,不能接elsif。

作为修饰符的if(if as a modifier)
采用if的普通语句形式时,ruby语法要求结尾必须有一个end。对于那些简单的、只有一行代码的条件式来说,这显得有些笨拙。这只是一个语法分析问题,解决之道就是将if语句本身作为分界符,将代码和条件式隔离开。这种情况下,我们通常不写成这样:
if exp then code end
而是写成:
code if exp
此时,if被称为语句(或表达式)修饰符。虽然条件式是后编写的,但他是先被求值的。如果不为false或nil,那么对应代码执行,否则,代码将不会执行,而且这个修饰表达式的返回值为nil。显而易见,这种语法不允许任何else从句。

(python可以,如:

>>> x=1
>>> name= x if x==1 else 5
>>> name
1
>>> name= x if x==5 else "hello"
>>> name
'hello'
>>>

:循环语句

while and until
Ruby’s basic looping statements are while and until. They execute a chunk of code
while a certain condition is true, or until the condition becomes true. For example:
x = 10 # Initialize a loop counter variable
while x >= 0 do # Loop while x is greater than or equal to 0
  puts x # Print out the value of x
  x = x - 1 # Subtract 1 from x
end # The loop ends here

# Count back up to 10 using an until loop
x = 0 # Start at 0 (instead of -1)
  until x > 10 do # Loop until x is greater than 10
  puts x
  x = x + 1
end # Loop ends here

 

作为修饰符的while和until

如果一个循环体仅包含一个ruby表达式,那么你可以将while和until作为修饰符置于该表达式之后,以一种非常紧凑的形式来表达该循环,比如:
x = 0 # Initialize loop variable
puts x = x + 1 while x < 10 # Output and increment in a single expression
在这种修饰符语法中,while关键字分隔了循环体和循环条件,从而省却了do(或换行符)和end关键提。
until也可以作为修饰符。
请注意:while和until作为修饰符时,他们必须和那些被他们所修饰的循环体处在同一行中

for in循环

The for loop, or for/in loop, iterates through the elements of an enumerable object
(such as an array). On each iteration, it assigns an element to a specified loop variable
and then executes the body of the loop. A for loop looks like this:
for var in collection do
   body
end
var is a variable or a comma-separated list of variables. collection is any object that
has an each iterator method. Arrays and hashes define the each method, and many other
Ruby objects do, too. The for/in loop calls the each method of the specified object. As
that iterator yields values, the for loop assigns each value (or each set of values) to the
specified variable (or variables) and then executes the code in body. As with the while
and until loops, the do keyword is optional and may be replaced with a newline or
semicolon.

注意:do关键字是可选的,可以被newline或分号替代。

当然,这么写没错:

  1. for key,value in hash do
  2. puts "#{key}=>#{value}"
  3. end

for循环对each迭代器方法的依赖意味着它非常像迭代器,比如,上面的例子可以写成这样:
hash = {:a=>1, :b=>2, :c=>3}
hash.each do |key,value|
puts "#{key} => #{value}"
end
循环的for版本和each版本之间的唯一差别在于,跟在一个迭代器之后的代码块会定义一个新的变量作用域,我们将在后面讨论迭代器的相关细节。

迭代器和可枚举对象(Iterators and enumerable objects)

虽然while,until和for循环是ruby语言的核心部分之一,但是通常情况下我们更倾向是使用一个特殊的方法来编写循环,那就是迭代器,迭代器是ruby最为重要的特性之一,下面是一些新手入门常用的例子:
3.times{ puts "hell"}
data.each {|x| puts x}
[1,2,3].map{|x| x*x}
factorial=1
2.upto(n) {|x| factorial*=x}

The times, each, map, and upto methods are all iterators, and they interact with the
block of code that follows them. The complex control structure behind this is yield.
The yield statement temporarily returns control from the iterator method to the method
that invoked the iterator. Specifically, control flow goes from the iterator to the block
of code associated with the invocation of the iterator. When the end of the block is
reached, the iterator method regains control and execution resumes at the first statement
following the yield. In order to implement some kind of looping construct, an
iterator method will typically invoke the yield statement multiple times. Figure 5-1
illustrates this complex flow of control. Blocks and yield are described in detail in
§5.4 below; for now, we focus on the iteration itself rather than the control structure
that enables it.

Iterators that Don’t Iterate。 “期待一个关联代码块的方法”

  1. chars = "hello world".tap {|x| puts "original object: #{x.inspect}"}
  2. .each_char .tap {|x| puts "each_char returns: #{x.inspect}"}
  3. .to_a .tap {|x| puts "to_a returns: #{x.inspect}"}
  4. .map {|c| c.succ } .tap {|x| puts "map returns: #{x.inspect}" }
  5. .sort .tap {|x| puts "sort returns: #{x.inspect}"}

each迭代器并不是那些传统的“数据结构”(数组,hash等)类的专利,ruby的IO类也定义了一个each迭代器,他可以把那些从输入/输出对象中读取出来的文本行传递尽量,因此在ruby中你可以像下面这样处理一个文件的行:

  1. filename="F:/ruby/rubySource/data.txt"
  2.  
  3. File.open(filename) do |f| #open named file,pass as f
  4. f.each { | line | print line}
  5. end

大多数定义了each方法的类都包含Enumerable模块,它定义了许多更特殊的迭代器,而他们都是基于each方法来实现的,each_with_index就是这些有用的迭代器其中之一。先前的例子,我们可以给每行添加一个行号:

  1. File.open(filename) do |f| #open named file,pass as f
  2. f.each_with_index { | line,number | print "#{number}:#{line}" }
  3. end

ruby条件控制结构的更多相关文章

  1. GNU Makefile中的条件控制结构

    在常见的编程语言中,使用条件控制结构诸如if ... else if ... else...是很寻常的事情,那么在GNU Makefile中如何使用呢? ifeq ifneq 例如:foo.sh #! ...

  2. ruby 条件判断&循环控制

    参考:https://www.jb51.net/article/66709.htm

  3. mac ruby rails安装(使用rvm)

    mac的场合: which ruby -> /usr/bin/ruby -> 这是mac自带的ruby,我们希望能用管理ruby的版本. 安装rvm curl -L https://get ...

  4. 4_PHP流程控制语句_1_条件控制语句

    以下为学习孔祥盛主编的<PHP编程基础与实例教程>(第二版)所做的笔记. PHP流程控制共有3种类型:条件控制结构.循环结构以及程序跳转和终止语句. 4.1 条件控制语句 4.1.1 if ...

  5. openresty开发系列16--lua中的控制结构if-else/repeat/for/while

    openresty开发系列16--lua中的控制结构if-else/repeat/for/while 一)条件 - 控制结构 if-else if-else 是我们熟知的一种控制结构.Lua 跟其他语 ...

  6. 动静结合?Ruby 和 Java 的基础语法比较(入门篇)

    前言 这篇文章示例代码比较多, Java 程序员可以看到一些 Ruby 相关语法和使用,Ruby 程序员可以看看 Java 的基本语法和使用方法,本文比较长,将近万字左右,预计需要十几分钟,如果有耐心 ...

  7. PostgreSQL-PL/pgSQL控制结构

    PL/pgSQL的控制结构是最重要及最有用的一部分了,在实际工作场景都离不开业务处理逻辑,在写PL/pgSQL时,利用控制结构来操作数据.PL/pgSQL支持的控制结构与其他语言几乎差不多,比如:条件 ...

  8. JVM 平台上的各种语言的开发指南

    JVM 平台上的各种语言的开发指南 为什么我们需要如此多的JVM语言? 在2013年你可以有50中JVM语言的选择来用于你的下一个项目.尽管你可以说出一大打的名字,你会准备为你的下一个项目选择一种新的 ...

  9. 尽量少用if else

    Michael Feathers是Object Mentor International公司的技术顾问.他的工作不仅是技术开发,他还参与对世界各地技术团队进行培训.指导等工作.他曾开发了将JUnit迁 ...

随机推荐

  1. 如何在已安装vs2010的基础上安装sql2008

    以前老受到别人写的这类东西的帮助,所以这次决定自己试下,第一次发这种,写得不好莫怪.       涉略sql2008一个多星期了.怎么说呢?Transact-SQL的编程虽然不如C++,java等高级 ...

  2. Asp.net中前台javascript与后台C#交互

    方法一:使用Ajax开发框架,后台方法定义前添加[AjaxPro.AjaxMethod],然后就可以在前台js脚本中调用后台C#函数. 方法二:后台方法声明为public或者protected,然后前 ...

  3. 20151215jqueryUI--dialog代码备份

    $(function () { $('#search_button').button(); /*$('#reg_a').click(function() { $('#reg').dialog(); } ...

  4. Android在onCreate()中获得控件尺寸

    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceSt ...

  5. 基于注解整合struts2与spring的时候如果不引入struts2-spring-plugin包自动装配无效

    基于注解整合struts2与spring的时候如果不引入struts2-spring-plugin包,自动装配将无效,需要spring注入的对象使用时将抛出空指针异常(NullPointerExcep ...

  6. javascript dom 编程艺术笔记 第四章:图片库

    首先先建立一个html文件,建立一个图片库 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" &q ...

  7. 'DEVENV' is not recognized as an internal or external command,

    使用命令行 DEVENV 编译c# 工程, C:\MyProject>DEVENV "MyProject.sln" /build Release /useenv'DEVENV ...

  8. ubuntu server修改时区

    公司用的是ubuntu server 服务器在美国亚马逊VPS 现在要修改时区 执行:tzselect 或直接修改 /etc/timezone 文件,我是改成(America/Los_Angeles) ...

  9. [CLR VIA C#] chapter2 building,packaging,deploying, and administering

    今天整理一下 assembly, 总感觉第一章 到 第三章 没怎么仔细看, 导致后面作者说前面说过的, 我就心里不舒服, 前面3章很干很涩, 好好啃啃, 先作一些简单笔记, 最后再来 整体整理, 反正 ...

  10. javascript读取本地文件

    由于浏览器考虑到安全问题,在修改本地文件方面除了IE几乎都不支持. IE例子 //读文件 function readFile(filename){ var fso = new ActiveXObjec ...