¿Cuál es la diferencia de declaración y expresión en Ruby?

I know in Ruby, almost everything is an expression. Even those in other language such as if-else declaración, case statement, assignment statement, loop statement is an expression in Ruby.

So I want to know from the Ruby's point of view, what's the difference between statement and expression?

preguntado el 09 de marzo de 12 a las 15:03

As you noticed correctly, there are no statements in Ruby, so the question doesn't really make sense. -

4 Respuestas

There is no difference between expressions and statement is Ruby. Everything evaluates to a value so everything is an expression.

respondido 09 mar '12, 15:03

Aún así, is una diferencia. a if b is a statement, but (a if b) becomes an expression. The consequence is that puts(a if b) is a SyntaxError but puts((a if b)) is ok, because method arguments must be expressions. - Daniel

Thanks fro the comment, @Daniel I wasn't aware of this subtlety. - Alejandro Pohl

De: Ruby hacking guide:

Also, function and class definitions are typically statements however in languages such as Lisp and Scheme, since everything is an expression, they do not have statements in the first place. Ruby is close to Lisp’s design in this regard.

These are the statement's grammar rules, where you can see (sort of) what is a statement in the language implementation. Notice the expr rule that means that a stmnt could be an expr. An expr could not be a stmt.

stmt        : kALIAS fitem  fitem
            | kALIAS tGVAR tGVAR
            | kALIAS tGVAR tBACK_REF
            | kALIAS tGVAR tNTH_REF
            | kUNDEF undef_list
            | stmt kIF_MOD expr_value
            | stmt kUNLESS_MOD expr_value
            | stmt kWHILE_MOD expr_value
            | stmt kUNTIL_MOD expr_value
            | stmt kRESCUE_MOD stmt
            | klBEGIN ‘{’ compstmt ‘}’
            | klEND ‘{’ compstmt ‘}’
            | lhs ‘=’ command_call
            | mlhs ‘=’ command_call
            | var_lhs tOP_ASGN command_call
            | primary_value ‘[’ aref_args ‘]’ tOP_ASGN command_call
            | primary_value ‘.’ tIDENTIFIER tOP_ASGN command_call
            | primary_value ‘.’ tCONSTANT tOP_ASGN command_call
            | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
            | backref tOP_ASGN command_call
            | lhs '=' mrhs_basic
            | mlhs '=' mrhs
            | expr

Respondido el 06 de junio de 16 a las 06:06

I'm surprised to see assignment here, since 1+(a=2) appears to be valid (irb 0.9.6 and ruby 2.3.7p456). - akim

Only assignments with a command_call, like x = foo 2, pero x = foo(2) is not a statement. - Daniel

Think of the expressions as small parts of a sentence. Think of the statement as that completed sentence or thought. One line in your method or loop could be an expression, and the conglomeration of those expressions into a closed loop or method could be thought of as a statement.

This is more or less conceptually subjective. As Niklas B. correctly pointed out (and you correctly noticed).

Is there an issue that you are dealing directly that made you look into this?

You'll also hear people say "everything in ruby is an object" more than everything is an expression.

respondido 09 mar '12, 15:03

I'd say that the main conceptual difference is whether the value of something is used or discarded. - Niklas B.

There is a difference. It's a subtle but important one. An expression is a type of statement. All expressions are statements but not all statements are expressions.

Most notably, statements that are not expressions include:

stmt if expr
stmt unless expr
stmt while expr
stmt until expr
stmt rescue expr
var = method expr
x,y = expr

When used as a modifier, if, else, while, until y rescue become statements, not expressions. This means they cannot be used in contexts where an expression is expected, such as method arguments. Wrap with parentheses to create an expression.

  puts( 1 if true )      #=> SyntaxError
  puts((1 if true))      #=> 1
  puts (1 if true)       #=> 1, because of optional parentheses for method

  puts( 1 rescue true )  #=> SyntaxError
  puts((1 rescue true))  #=> 1
  puts (1 rescue true)   #=> 1, because of optional parentheses for method

The right-hand side of a modifier statement is also one of those contexts where an expression is expected. So in a if b rescue c, porque b rescue c is a statement and therefore not allowed as the condition of the if statement, the code is necessarily parsed as (a if b) rescue c.

This interacts with operator precedence in such a way that:

 stmt if v = expr rescue x
 stmt if     expr rescue x
 stmt if v = expr unless x
 stmt if     expr unless x

are parsed as:

 stmt if v = (expr rescue x)
 (stmt if     expr) rescue x
 (stmt if v = expr) unless x
 (stmt if     expr) unless x

Respondido 27 ago 19, 20:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.