Movatterモバイル変換


[0]ホーム

URL:


HomeClassesMethods

Files

Class Index[+]

Quicksearch
No matching classes.

Control Expressions

Ruby has a variety of ways to control execution. All the expressionsdescribed here return a value.

For the tests in these control expressions,nil andfalse are false-values andtrue and any otherobject are true-values. In this document “true” will mean “true-value” and“false” will mean “false-value”.

if Expression

The simplestif expression has two parts, a “test” expressionand a “then” expression. If the “test” expression evaluates to a true thenthe “then” expression is evaluated.

Here is a simple if statement:

iftruethenputs"the test resulted in a true-value"end

This will print “the test resulted in a true-value”.

Thethen is optional:

iftrueputs"the test resulted in a true-value"end

This document will omit the optionalthen for all expressionsas that is the most common usage ofif.

You may also add anelse expression. If the test does notevaluate to true theelse expression will be executed:

iffalseputs"the test resulted in a true-value"elseputs"the test resulted in a false-value"end

This will print “the test resulted in a false-value”.

You may add an arbitrary number of extra tests to an if expression usingelsif. Anelsif executes when all tests abovetheelsif are false.

a =1ifa==0puts"a is zero"elsifa==1puts"a is one"elseputs"a is some other value"end

This will print “a is one” as1 is not equal to0. Sinceelse is only executed when there are nomatching conditions.

Once a condition matches, either theif condition or anyelsif condition, theif expression is completeand no further tests will be performed.

Like anif, anelsif condition may be followed byathen.

In this example only “a is one” is printed:

a =1ifa==0puts"a is zero"elsifa==1puts"a is one"elsifa>=1puts"a is greater than or equal to one"elseputs"a is some other value"end

The tests forif andelsif may have side-effects.The most common use of side-effect is to cache a value into a localvariable:

ifa =object.some_value# do something to aend

The result value of anif expression is the last valueexecuted in the expression.

Ternary if

You may also write a if-then-else expression using? and:. This ternary if:

input_type =gets=~/hello/i?"greeting":"other"

Is the same as thisif expression:

input_type =ifgets=~/hello/i"greeting"else"other"end

While the ternary if is much shorter to write than the more verbose form,for readability it is recommended that the ternary if is only used forsimple conditionals. Also, avoid using multiple ternary conditions in thesame expression as this can be confusing.

unless Expression

Theunless expression is the opposite of theifexpression. If the value is false, the “then” expression is executed:

unlesstrueputs"the value is a false-value"end

This prints nothing as true is not a false-value.

You may use an optionalthen withunless justlikeif.

Note that the aboveunless expression is the same as:

ifnottrueputs"the value is a false-value"end

Like anif expression you may use anelsecondition withunless:

unlesstrueputs"the value is false"elseputs"the value is true"end

This prints “the value is true” from theelse condition.

You may not useelsif with anunless expression.

The result value of anunless expression is the last valueexecuted in the expression.

Modifierif andunless

if andunless can also be used to modify anexpression. When used as a modifier the left-hand side is the “then”statement and the right-hand side is the “test” expression:

a =0a+=1ifa.zero?pa

This will print 1.

a =0a+=1unlessa.zero?pa

This will print 0.

While the modifier and standard versions have both a “test” expression anda “then” statement, they are not exact transformations of each other due toparse order. Here is an example that shows the difference:

paifa =0.zero?

This raises theNameError “undefinedlocal variable or method `a'”.

When ruby parses this expression it first encountersa as amethod call in the “then” expression, then later it sees the assignment toa in the “test” expression and marksa as a localvariable.

When running this line it first executes the “test” expression,a =0.zero?.

Since the test is true it executes the “then” expression,p a.Since thea in the body was recorded as a method which doesnot exist theNameError is raised.

The same is true forunless.

case Expression

Thecase expression can be used in two ways.

The most common way is to compare an object against multiple patterns. Thepatterns are matched using the +===+ method which is aliased to +==+ onObject. Other classes must override it togive meaningful behavior. SeeModule#=== andRegexp#=== for examples.

Here is an example of usingcase to compare aString against a pattern:

case"12345"when/^1/puts"the string starts with one"elseputs"I don't know what the string starts with"end

Here the string"12345" is compared with/^1/ by calling/^1/ === "12345" whichreturnstrue. Like theif expression, the firstwhen that matches is executed and all other matches areignored.

If no matches are found, theelse is executed.

Theelse andthen are optional, thiscase expression gives the same result as the one above:

case"12345"when/^1/puts"the string starts with one"end

You may place multiple conditions on the samewhen:

case"2"when/^1/,"2"puts"the string starts with one or is '2'"end

Ruby will try each condition in turn, so first/^1/ ==="2" returnsfalse, then"2"=== "2" returnstrue, so “the string startswith one or is '2'” is printed.

You may usethen after thewhen condition. Thisis most frequently used to place the body of thewhen on asingle line.

caseawhen1,2thenputs"a is one or two"when3thenputs"a is three"elseputs"I don't know what a is"end

The other way to use acase expression is like an if-elsifexpression:

a =2casewhena==1,a==2puts"a is one or two"whena==3puts"a is three"elseputs"I don't know what a is"end

Again, thethen andelse are optional.

The result value of acase expression is the last valueexecuted in the expression.

Since Ruby 2.7,case expressions also provide a more powerfulexperimental pattern matching feature via thein keyword:

case {a: 1, b: 2, c: 3}in a: Integer => m  "matched: #{m}"else  "not matched"end# => "matched: 1"

The pattern matching syntax is described on its own page.

while Loop

Thewhile loop executes while a condition is true:

a =0whilea<10dopaa+=1endpa

Prints the numbers 0 through 10. The conditiona < 10 ischecked before the loop is entered, then the body executes, then thecondition is checked again. When the condition results in false the loopis terminated.

Thedo keyword is optional. The following loop is equivalentto the loop above:

whilea<10paa+=1end

The result of awhile loop isnil unlessbreak is used to supply a value.

until Loop

Theuntil loop executes while a condition is false:

a =0untila>10dopaa+=1endpa

This prints the numbers 0 through 11. Like a while loop the conditiona > 10 is checked when entering the loop and each time theloop body executes. If the condition is false the loop will continue toexecute.

Like awhile loop, thedo is optional.

Like awhile loop, the result of anuntil loop isnil unlessbreak is used.

for Loop

Thefor loop consists offor followed by avariable to contain the iteration argument followed byin andthe value to iterate over using each. Thedo is optional:

forvaluein [1,2,3]doputsvalueend

Prints 1, 2 and 3.

Likewhile anduntil, thedo isoptional.

Thefor loop is similar to using each, but does not create anew variable scope.

The result value of afor loop is the value iterated overunlessbreak is used.

Thefor loop is rarely used in modern ruby programs.

Modifierwhile anduntil

Likeif andunless,while anduntil can be used as modifiers:

a =0a+=1whilea<10pa# prints 10

until used as a modifier:

a =0a+=1untila>10pa# prints 11

You can usebegin andend to create awhile loop that runs the body once before the condition:

a =0begina+=1endwhilea<10pa# prints 10

If you don't userescue orensure, Rubyoptimizes away any exception handling overhead.

break Statement

Usebreak to leave a block early. This will stop iteratingover the items invalues if one of them is even:

values.eachdo|value|breakifvalue.even?# ...end

You can also terminate from awhile loop usingbreak:

a =0whiletruedopaa+=1breakifa<10endpa

This prints the numbers 0 and 1.

break accepts a value that supplies the result of theexpression it is “breaking” out of:

result = [1,2,3].eachdo|value|breakvalue*2ifvalue.even?endpresult# prints 4

next Statement

Usenext to skip the rest of the current iteration:

result = [1,2,3].mapdo|value|nextifvalue.even?value*2endpresult# prints [2, nil, 6]

next accepts an argument that can be used as the result of thecurrent block iteration:

result = [1,2,3].mapdo|value|nextvalueifvalue.even?value*2endpresult# prints [2, 2, 6]

redo Statement

Useredo to redo the current iteration:

result = []whileresult.length<10doresult<<result.lengthredoifresult.last.even?result<<result.length+1endpresult

This prints [0, 1, 3, 3, 5, 5, 7, 7, 9, 9, 11]

In Ruby 1.8, you could also useretry where you usedredo. This is no longer true, now you will receive aSyntaxError when you useretry outside of arescue block. See Exceptionsfor proper usage ofretry.

Modifier Statements

Ruby's grammar differentiates between statements and expressions. Allexpressions are statements (an expression is a type of statement), but notall statements are expressions. Some parts of the grammar acceptexpressions and not other types of statements, which causes code that lookssimilar to be parsed differently.

For example, when not used as a modifier,if,else,while,until, andbegin are expressions (and also statements). However, whenused as a modifier,if,else,while,until andrescue are statements but notexpressions.

iftrue;1end# expression (and therefore statement)1iftrue# statement (not expression)

Statements that are not expressions cannot be used in contexts where anexpression is expected, such as method arguments.

puts( 1 if true )      #=> SyntaxError

You can wrap a statement in parentheses to create an expression.

puts((1iftrue))#=> 1

If you put a space between the method name and opening parenthesis, you donot need two sets of parentheses.

puts (1iftrue)#=> 1, because of optional parentheses for method

This is because this is parsed similar to a method call withoutparentheses. It is equivalent to the following code, without the creationof a local variable:

x = (1iftrue)px

In a modifier statement, the left-hand side must be a statement and theright-hand side must be an expression.

So ina if b rescue c, becauseb rescue c is astatement that is not an expression, and therefore is not allowed as theright-hand side of theif modifier statement, the code isnecessarily parsed as(a if b) rescue c.

This interacts with operator precedence in such a way that:

stmtifv =exprrescuexstmtifv =exprunlessx

are parsed as:

stmtifv = (exprrescuex)(stmtifv =expr)unlessx

This is because modifierrescue has higher precedence than=, and modifierif has lower precedence than=.

Flip-Flop

The flip-flop is a rarely seen conditional expression. It's primaryuse is for processing text from ruby one-line programs used withruby-n orruby -p.

The form of the flip-flop is an expression that indicates when theflip-flop turns on,.. (or...), then anexpression that indicates when the flip-flop will turn off. While theflip-flop is on it will continue to evaluate totrue, andfalse when off.

Here is an example:

selected = []0.upto10do|value|selected<<valueifvalue==2..value==8endpselected# prints [2, 3, 4, 5, 6, 7, 8]

In the above example, the on condition isn==2. The flip-flopis initially off (false) for 0 and 1, but becomes on (true) for 2 andremains on through 8. After 8 it turns off and remains off for 9 and 10.

The flip-flop must be used inside a conditional such asif,while,unless,until etc. includingthe modifier forms.

When you use an inclusive range (..), the off condition isevaluated when the on condition changes:

selected = []0.upto5do|value|selected<<valueifvalue==2..value==2endpselected# prints [2]

Here, both sides of the flip-flop are evaluated so the flip-flop turns onand off only whenvalue equals 2. Since the flip-flop turnedon in the iteration it returns true.

When you use an exclusive range (...), the off condition isevaluated on the following iteration:

selected = []0.upto5do|value|selected<<valueifvalue==2...value==2endpselected# prints [2, 3, 4, 5]

Here, the flip-flop turns on whenvalue equals 2, butdoesn't turn off on the same iteration. The off condition isn'tevaluated until the following iteration andvalue will neverbe two again.

Generated with Rubydoc Rdoc Generator 0.42.0.


[8]ページ先頭

©2009-2025 Movatter.jp