Does Ruby/Rails have a ++ equivalent? - ruby-on-rails

I guess I just got used to saying things like:
x++
in PHP and Java land. But when I tried this in my Rails code it had a fit:
compile error
/users/gshankar/projects/naplan/app/views/answers/new.html.haml:19: syntax error, unexpected ';'
/users/gshankar/projects/naplan/app/views/answers/new.html.haml:23: syntax error, unexpected kENSURE, expecting kEND
...}\n", 0, false);_erbout;ensure;#haml_buffer = #haml_buffer.u...
^
/users/gshankar/projects/naplan/app/views/answers/new.html.haml:26: syntax error, unexpected $end, expecting kEND
I googled around a bit for Ruby/Rails operators for a reference to ++ but couldn't find anything. For a language which focuses on writing less I find it a bit strange that there wouldn't be a ++ equivalent. Am I missing something?

Try this:
x += 1

x+=1 is the best you can do in Ruby.
For a detailed explanation, see Why doesn't Ruby support i++ or i--​ (increment/decrement operators)?

While as other answers point out x += 1 and x -= 1 is one way to do this. The closest Ruby gets to the --/++ operators are the prev()/next() (next has an alias of succ()) methods which return the previous/next items in sequence and are available on unambiguous strictly ordered classes (like String).
x = 4 # => 4
x.succ # => 5
x.prev # => 3
y = 'ABC' # => 'ABC'
y.succ # => 'ABD'
y.prev # => 'ABB'
Unfortunately, none of these implicitly do assignment which is what the original question was asking about. igul222's answer links to a post from Ruby's creator explaining why this is not possible.
Ruby has very powerful collection processing capabilities that eliminate most needs for these kinds of assignments. In all but the most complex alogrithms, which involve processing multiple collections at different rates in parallel. You should be asking yourself why you need increment/decrement. Because the Ruby way to do operations where increment and decrement operators are commonly used is with an iterator.
Such as each_with_index which executes a given block for each element/index pair in the array.
For example, this code will iterate through an array outputting the string representation fo each element and the parity of its index.
array = ["first", "second", "third","fourth","last"]
array.each_with_index do |object,index|
puts index % 2 ? "even" : "odd"
puts object.to_s
end
Edit: Removed Fixnum extension providing postfix increment because it doesn't work. Upon closer inspection there's nothing stopping you from adding it, but it would involve writing your feature in C, and a recompile.
Edit 2022: Added comment about prev/next/succ functions which are closer in behaviour to the decrement/increment function of --/++ operators

You have to use x+=1 instead.
http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Operators

Related

Getting date parts from a simple treetop parser: wrong argument type Class (expected Module)

For the following treetop grammer, when parsing '3/14/01' (via t = Parser.parse('3/14/01') in irb), I get a "TypeError: wrong argument type Class (expected Module)".
grammar SimpleDate
rule dateMDY
whitespace? month_part ( '/' / '-') day_part ( ('/' / '-') year_part)? whitespace? <DateMDY>
end
rule month_part
( ( '1' [0-2] ) / ( '0'? [1-9] ) ) <MonthLiteral>
end
rule day_part
( ( [12] [0-9] ) / ( '3' [0-1] ) / ( '0'? [1-9] ) ) <DayLiteral>
end
rule year_part
( ( '1' '9' ) / ( '2' [01] ) )? [0-9] [0-9] <YearLiteral> # 1900 through 2199 (4 digit)
end
rule whitespace
[\s]+
end
end
First,
if I comment out the <MonthLiteral> and the <DayLiteral> class references, all is well. Commenting out <DateMDY>, but leaving those Literal objects in, will also issue the error. Commenting out <YearLiteral> does not seem to matter (it'll work or not work regardless) -- that seems to indicate that because the first two are non-terminal, I can't produce elements for them.
There is clearly something I'm not appreciating about how Ruby (or treetop) is instantiating these classes or about AST generation that would explain what happens. Can you explain or point me to something that can help me understand why <MonthLiteral> or <DayLiteral> can't have objects generated?
Second,
this may be a bridge too far, but what I'd really prefer would be to get a DateMDY object with three attributes -- month, day, and year -- so I can readily produce a Ruby Time object from a method to_time in DateMDY, but right now I'd settle for just producing the constituent pieces as objects.
So I tried leaving <DateMDY> as the object and commented out the references to <MonthLiteral>, <DayLiteral>, and <YearLiteral>. I saw that the resulting AST object returned from .parse (t in my original example) has two public methods -- :day_part and :month_part but those seem to be nil when I invoke those (say, puts t.day_part) and there is no :year_part method, so that didn't seem to help me out.
Is it possible to do somehow have DateMDY end up accessing its constituent parts?
FYI, the Parser code itself I'm using is pretty standard stuff from the treetop tutorials and the node_extensions.rb that defines the object classes is also trivial, but I can post those too if you need to see those.
Thanks!
Richard
The error message is telling you exactly what you did wrong. There's only a restricted set of places where you can use a Class this way. When it's allowed, the Class must be a subclass of SyntaxNode. Normally however you should use a Module, which is extend()ed into the SyntaxNode that has been created by an inner rule. The difference in the case of YearLiteral is it does not wrap a parenthesised sequence the way Month and Day literal do. This parenthesised sequence returns an existing SyntaxNode, which cannot be extend()ed with another Class, only with a Module, so you get the TypeError.
As for your second question, the DateMDY object you want should almost certainly not be a SyntaxNode - since all SyntaxNodes retain references to all their child SyntaxNodes and to the input string - this is the parser internals we're talking about. Do you really want to expose bits of the parser internals to the outside world?
Instead, you should arrange for the appropriate syntax node to be visited after the parse has completed, by calling a function that returns your domain object type constructed using the substrings identified and saved by these parser objects. It's best to add these functions to traverse down from your topmost rule, rather than trying to traverse the parse tree "from the outside".
You can do this by adding a block into your top rule, like this (assuming you have an appropriate DateMDY class). When you have a successful parse tree, get your DateMDY by calling "tree.result":
rule dateMDY
whitespace? month_part ( '/' / '-') day_part y:( ('/' / '-') year_part)? whitespace?
{
def result
DateMDY.new(y.empty? ? nil : y.year_part.text_value.to_i,
month_part.text_value.to_i,
day_part.text_value.to_i)
end
}
end
Of course, it's cleaner to add separate result methods for year_part, month_part and day_part; this is just an intro to how to add these methods.

Why are redundant parenthesis not allowed in syntax definitions?

This syntax module is syntactically valid:
module mod1
syntax Empty =
;
And so is this one, which should be an equivalent grammar to the previous one:
module mod2
syntax Empty =
( )
;
(The resulting parser accepts only empty strings.)
Which means that you can make grammars such as this one:
module mod3
syntax EmptyOrKitchen =
( ) | "kitchen"
;
But, the following is not allowed (nested parenthesis):
module mod4
syntax Empty =
(( ))
;
I would have guessed that redundant parenthesis are allowed, since they are allowed in things like expressions, e.g. ((2)) + 2.
This problem came up when working with the data types for internal representation of rascal syntax definitions. The following code will create the same module as in the last example, namely mod4 (modulo some whitespace):
import Grammar;
import lang::rascal::format::Grammar;
str sm1 = definition2rascal(\definition("unknown_main",("the-module":\module("unknown",{},{},grammar({sort("Empty")},(sort("Empty"):prod(sort("Empty"),[
alt({seq([])})
],{})))))));
The problematic part of the data is on its own line - alt({seq([])}). If this code is changed to seq([]), then you get the same syntax module as mod2. If you further delete this whole expression, i.e. so that you get this:
str sm3 =
definition2rascal(\definition("unknown_main",("the-module":\module("unknown",{},{},grammar({sort("Empty")},(sort("Empty"):prod(sort("Empty"),[
], {})))))));
Then you get mod1.
So should such redundant parenthesis by printed by the definition2rascal(...) function? And should it matter with regards to making the resulting module valid or not?
Why they are not allowed is basically we wanted to see if we could do without. There is currently no priority relation between the symbol kinds, so in general there is no need to have a bracket syntax (like you do need to + and * in expressions).
Already the brackets have two different semantics, one () being the epsilon symbol and two (Sym1 Sym2 ...) being a nested sequence. This nested sequence is defined (syntactically) to expect at least two symbols. Now we could without ambiguity introduce a third semantics for the brackets with a single symbol or relax the requirement for sequence... But we reckoned it would be confusing that in one case you would get an extra layer in the resulting parse tree (sequence), while in the other case you would not (ignored superfluous bracket).
More detailed wise, the problem of printing seq([]) is not so much a problem of the meta syntax but rather that the backing abstract notation is more relaxed than the concrete notation (i.e. it is a bigger language or an over-approximation). The parser generator will generate a working parser for seq([]). But, there is no Rascal notation for an empty sequence and I guess the pretty printer should throw an exception.

ArgumentError: invalid radix -1

In a rails 3.2 , ruby 1.9.3 app
Trying to perform a simple -1 action on an integer:
doing this on the model:
order_details[:quantity].to_i - 1
and getting the ArgumentError: invalid radix -1
Tried to look this up online , and found very little documentation.
Any help, pls?
I'm assuming order_details[:quantity] is a String (though the answer is the same regardless).
String#to_i takes an optional argument for the base the number is to be interpreted as. For instance "10101".to_i(2) will parse as base 2, (giving the decimal 21 as a result). Your line of code is being interpreted as
order_details[:quantity].to_i(-1)
and since a base of negative one (-1) makes no sense, it's giving you that error. The solution is to put parentheses around order_details[:quantity].to_i so that it's evaluated first:
(order_details[:quantity].to_i) - 1
Edit:
Or, make sure there's a space separating - from the two arguments (or no spaces on either side) and Ruby should parse it correctly. It might be that your actual code is written as order_details[:quantity].to_i -1 (note no space between - and 1) causing it to read -1 and then pass it as an argument to to_i.
I think your problem is that your code really looks like this:
order_details[:quantity].to_i -1 # with the minus sign right next to the one
Ruby is parsing this as:
order_details[:quantity].to_i(-1)
Method parameters do not (always) need to be wrapped in parenthesis in Ruby, and to_i takes a parameter that specifies the base in which you are counting.
So you could convert base 16 into our normal base ten like:
"0xA".to_i(16)
iamnotmaynard correctly identified it as a syntax error, but I think it's that you need to separate the - and 1. You could put parenthesis around the first element (it works), but that's more short-circuiting improper syntax instead of supplying proper syntax.
Try separating the elements out without parenthesis:
order_details[:quantity].to_i - 1 # with the space between the 1 and minus sign

Accidental expression evaluation in ruby

Why this expression evaluating to 13 ?.
I accidentally evaluated this expression (1_2).next instead of (1+2).next which o/p 4 as result.
=> (1_2).next
=> 13
Please let me know how this is, as i m new to Ruby
Ruby allows you to use _ to break up long numbers, for example
123456789 == 123_456_789
but the latter is a little easier to read, so your code is the same as 12.next
1_2 is the same as 12. 12.next is 13. Underscores in numbers are ignored, you can use them for readability. E.g. 1000_000_000 is one billion.

REBOL path operator vs division ambiguity

I've started looking into REBOL, just for fun, and as a fan of programming languages, I really like seeing new ideas and even just alternative syntaxes. REBOL is definitely full of these. One thing I noticed is the use of '/' as the path operator which can be used similarly to the '.' operator in most object-oriented programming languages. I have not programmed in REBOL extensively, just looked at some examples and read some documentation, but it isn't clear to me why there's no ambiguity with the '/' operator.
x: 4
y: 2
result: x/y
In my example, this should be division, but it seems like it could just as easily be the path operator if x were an object or function refinement. How does REBOL handle the ambiguity? Is it just a matter of an overloaded operator and the type system so it doesn't know until runtime? Or is it something I'm missing in the grammar and there really is a difference?
UPDATE Found a good piece of example code:
sp: to-integer (100 * 2 * length? buf) / d/3 / 1024 / 1024
It appears that arithmetic division requires whitespace, while the path operator requires no whitespace. Is that it?
This question deserves an answer from the syntactic point of view. In Rebol, there is no "path operator", in fact. The x/y is a syntactic element called path. As opposed to that the standalone / (delimited by spaces) is not a path, it is a word (which is usually interpreted as the division operator). In Rebol you can examine syntactic elements like this:
length? code: [x/y x / y] ; == 4
type? first code ; == path!
type? second code
, etc.
The code guide says:
White-space is used in general for delimiting (for separating symbols).
This is especially important because words may contain characters such as + and -.
http://www.rebol.com/r3/docs/guide/code-syntax.html
One acquired skill of being a REBOler is to get the hang of inserting whitespace in expressions where other languages usually do not require it :)
Spaces are generally needed in Rebol, but there are exceptions here and there for "special" characters, such as those delimiting series. For instance:
[a b c] is the same as [ a b c ]
(a b c) is the same as ( a b c )
[a b c]def is the same as [a b c] def
Some fairly powerful tools for doing introspection of syntactic elements are type?, quote, and probe. The quote operator prevents the interpreter from giving behavior to things. So if you tried something like:
>> data: [x [y 10]]
>> type? data/x/y
>> probe data/x/y
The "live" nature of the code would dig through the path and give you an integer! of value 10. But if you use quote:
>> data: [x [y 10]]
>> type? quote data/x/y
>> probe quote data/x/y
Then you wind up with a path! whose value is simply data/x/y, it never gets evaluated.
In the internal representation, a PATH! is quite similar to a BLOCK! or a PAREN!. It just has this special distinctive lexical type, which allows it to be treated differently. Although you've noticed that it can behave like a "dot" by picking members out of an object or series, that is only how it is used by the DO dialect. You could invent your own ideas, let's say you make the "russell" command:
russell [
x: 10
y: 20
z: 30
x/y/z
(
print x
print y
print z
)
]
Imagine that in my fanciful example, this outputs 30, 10, 20...because what the russell function does is evaluate its block in such a way that a path is treated as an instruction to shift values. So x/y/z means x=>y, y=>z, and z=>x. Then any code in parentheses is run in the DO dialect. Assignments are treated normally.
When you want to make up a fun new riff on how to express yourself, Rebol takes care of a lot of the grunt work. So for example the parentheses are guaranteed to have matched up to get a paren!. You don't have to go looking for all that yourself, you just build your dialect up from the building blocks of all those different types...and hook into existing behaviors (such as the DO dialect for basics like math and general computation, and the mind-bending PARSE dialect for some rather amazing pattern matching muscle).
But speaking of "all those different types", there's yet another weirdo situation for slash that can create another type:
>> type? quote /foo
This is called a refinement!, and happens when you start a lexical element with a slash. You'll see it used in the DO dialect to call out optional parameter sets to a function. But once again, it's just another symbolic LEGO in the parts box. You can ascribe meaning to it in your own dialects that is completely different...
While I didn't find any written definitive clarification, I did also find that +,-,* and others are valid characters in a word, so clearly it requires a space.
x*y
Is a valid identifier
x * y
Performs multiplication. It looks like the path operator is just another case of this.

Resources