When, if ever, to use the Ruby keyword "for" - ruby

I personally like to iterate using the for keyword in Ruby since it reads very clean, from my eye. I generally assume that for may be an alias to Enumerable#each, but I do not know whether is is correct. In the most basic example:
for i in (1..10)
puts i
end
behaves the same as
(1..10).each do |i|
puts i
end
just without creating a new variable scope. Moreover, ruby-doc says
The for loop is rarely used in modern ruby programs.
which makes me feel there is a specific, technical reason against the usage. Does it matter that there's no new variable scope? In what way?

behaves the same as
This is incorrect. for is built on top of each, but it is semantically distinct:
array = %w(a b c d)
array.each { |character| }
defined? character # nil
for character in array; end
defined? character # "local-variable"
The for keyword doesn't introduce a new scope. Any variables introduced inside the block remain visible outside of it; as if it was written inline.
You should take this fact into account when you decide which form to use.

Related

"NoMethodError: undefined method '-#' for ["some-text"]:Array" when inside while loop [duplicate]

The pre/post increment/decrement operator (++ and --) are pretty standard programing language syntax (for procedural and object-oriented languages, at least).
Why doesn't Ruby support them? I understand you could accomplish the same thing with += and -=, but it just seems oddly arbitrary to exclude something like that, especially since it's so concise and conventional.
Example:
i = 0 #=> 0
i += 1 #=> 1
i #=> 1
i++ #=> expect 2, but as far as I can tell,
#=> irb ignores the second + and waits for a second number to add to i
I understand Fixnum is immutable, but if += can just instanciate a new Fixnum and set it, why not do the same for ++?
Is consistency in assignments containing the = character the only reason for this, or am I missing something?
Here is how Matz(Yukihiro Matsumoto) explains it in an old thread:
Hi,
In message "[ruby-talk:02706] X++?"
on 00/05/10, Aleksi Niemelä <aleksi.niemela#cinnober.com> writes:
|I got an idea from http://www.pragprog.com:8080/rubyfaq/rubyfaq-5.html#ss5.3
|and thought to try. I didn't manage to make "auto(in|de)crement" working so
|could somebody help here? Does this contain some errors or is the idea
|wrong?
(1) ++ and -- are NOT reserved operator in Ruby.
(2) C's increment/decrement operators are in fact hidden assignment.
They affect variables, not objects. You cannot accomplish
assignment via method. Ruby uses +=/-= operator instead.
(3) self cannot be a target of assignment. In addition, altering
the value of integer 1 might cause severe confusion throughout
the program.
matz.
One reason is that up to now every assignment operator (i.e. an operator which changes a variable) has a = in it. If you add ++ and --, that's no longer the case.
Another reason is that the behavior of ++ and -- often confuse people. Case in point: The return value of i++ in your example would actually be 1, not 2 (the new value of i would be 2, however).
It's not conventional in OO languages. In fact, there is no ++ in Smalltalk, the language that coined the term "object-oriented programming" (and the language Ruby is most strongly influenced by). What you mean is that it's conventional in C and languages closely imitating C. Ruby does have a somewhat C-like syntax, but it isn't slavish in adhering to C traditions.
As for why it isn't in Ruby: Matz didn't want it. That's really the ultimate reason.
The reason no such thing exists in Smalltalk is because it's part of the language's overriding philosophy that assigning a variable is fundamentally a different kind of thing than sending a message to an object — it's on a different level. This thinking probably influenced Matz in designing Ruby.
It wouldn't be impossible to include it in Ruby — you could easily write a preprocessor that transforms all ++ into +=1. but evidently Matz didn't like the idea of an operator that did a "hidden assignment." It also seems a little strange to have an operator with a hidden integer operand inside of it. No other operator in the language works that way.
I think there's another reason: ++ in Ruby wouldn't be remotely useful as in C and its direct successors.
The reason being, the for keyword: while it's essential in C, it's mostly superfluous in Ruby. Most of the iteration in Ruby is done through Enumerable methods, such as each and map when iterating through some data structure, and Fixnum#times method, when you need to loop an exact number of times.
Actually, as far as I have seen, most of the time +=1 is used by people freshly migrated to Ruby from C-style languages.
In short, it's really questionable if methods ++ and -- would be used at all.
You can define a .+ self-increment operator:
class Variable
def initialize value = nil
#value = value
end
attr_accessor :value
def method_missing *args, &blk
#value.send(*args, &blk)
end
def to_s
#value.to_s
end
# pre-increment ".+" when x not present
def +(x = nil)
x ? #value + x : #value += 1
end
def -(x = nil)
x ? #value - x : #value -= 1
end
end
i = Variable.new 5
puts i #=> 5
# normal use of +
puts i + 4 #=> 9
puts i #=> 5
# incrementing
puts i.+ #=> 6
puts i #=> 6
More information on "class Variable" is available in "Class Variable to increment Fixnum objects".
I think Matz' reasoning for not liking them is that it actually replaces the variable with a new one.
ex:
a = SomeClass.new
def a.go
'hello'
end
# at this point, you can call a.go
# but if you did an a++
# that really means a = a + 1
# so you can no longer call a.go
# as you have lost your original
Now if somebody could convince him that it should just call #succ! or what not, that would make more sense, and avoid the problem. You can suggest it on ruby core.
And in the words of David Black from his book "The Well-Grounded Rubyist":
Some objects in Ruby are stored in variables as immediate values. These include
integers, symbols (which look like :this), and the special objects true, false, and
nil. When you assign one of these values to a variable (x = 1), the variable holds
the value itself, rather than a reference to it.
In practical terms, this doesn’t matter (and it will often be left as implied, rather than
spelled out repeatedly, in discussions of references and related topics in this book).
Ruby handles the dereferencing of object references automatically; you don’t have to
do any extra work to send a message to an object that contains, say, a reference to
a string, as opposed to an object that contains an immediate integer value.
But the immediate-value representation rule has a couple of interesting ramifications,
especially when it comes to integers. For one thing, any object that’s represented
as an immediate value is always exactly the same object, no matter how many
variables it’s assigned to. There’s only one object 100, only one object false, and
so on.
The immediate, unique nature of integer-bound variables is behind Ruby’s lack of
pre- and post-increment operators—which is to say, you can’t do this in Ruby:
x = 1
x++ # No such operator
The reason is that due to the immediate presence of 1 in x, x++ would be like 1++,
which means you’d be changing the number 1 to the number 2—and that makes
no sense.
Some objects in Ruby are stored in variables as immediate values. These include integers, symbols (which look like :this), and the special objects true, false, and nil. When you assign one of these values to a variable (x = 1), the variable holds the value itself, rather than a reference to it.
Any object that’s represented as an immediate value is always exactly the same object, no matter how many variables it’s assigned to. There’s only one object 100, only one object false, and so on.
The immediate, unique nature of integer-bound variables is behind Ruby’s lack of pre-and post-increment operators—which is to say, you can’t do this in Ruby:
x=1
x++ # No such operator
The reason is that due to the immediate presence of 1 in x, x++ would be like 1++, which means you’d be changing the number 1 to the number 2—and that makes no sense.
Couldn't this be achieved by adding a new method to the fixnum or Integer class?
$ ruby -e 'numb=1;puts numb.next'
returns 2
"Destructive" methods seem to be appended with ! to warn possible users, so adding a new method called next! would pretty much do what was requested ie.
$ ruby -e 'numb=1; numb.next!; puts numb'
returns 2 (since numb has been incremented)
Of course, the next! method would have to check that the object was an integer variable and not a real number, but this should be available.

Are "begin" and "end" reserved words or not?

I'm kind of confused about reserved words in Ruby.
"The Ruby Programming Language", co-authored by Matz, says that begin and end are reserved words of the language. They're certainly used syntactically to mark out blocks.
However, range objects in the language have methods named begin and end, as in
(1..10).end
=> 10
Now, testing this out, I find that, indeed, I can define methods named "begin" and "end" on objects, though if I try to name a variable "begin" it fails. (Here's a sample of using it as a method name, it actually works...:)
class Foo
def begin
puts "hi"
end
end
Foo.new.begin
So, I suppose I'm asking, what actually is the status of reserved words like this? I would have imagined that they couldn't be used for method names (and yet it seems to work) or that at the very least it would be terrible style (but it is actually used in the core language for the Range class).
I'm pretty confused as to when they're allowed to be used and for what. Is there even documentation on this?
Yes, they are reserved words. Yes, they can be used for method names. No, you can't call them without an explicit receiver. It's probably not a good idea anyway.
class Foo
def if(foo)
puts foo
end
end
Foo.new.if("foo") # outputs foo, returns nil
Update: Here's a quote from "The Ruby Programming Language", by Matz (the creator of Ruby) himself:
In most languages, these words would be called “reserved words” and
they would be never allowed as identifiers. The Ruby parser is
flexible and does not complain if you prefix these keywords with #,
##, or $ prefixes and use them as instance, class, or global variable
names. Also, you can use these keywords as method names, with the
caveat that the method must always be explicitly invoked through an
object.
When they are given in a form that is unambiguously a method call, you can use them. If you have a period in front of it .begin or have parentheses after is begin(), then it is unambiguously a method call. When you try to use it as a variable begin, it is ambiguous (in principle).
Actually, as Perry, notes, begin() might be tricky. I checked with irb with Ruby 1.9.3, and the following strange thing happens:
irb(main):001:0> def begin(foo)
irb(main):002:1> puts 'a'
irb(main):003:1> end
=> nil
irb(main):004:0> begin(3)
irb(main):005:1>
irb(main):006:1* end
=> 3
It is not defined, and what looks like a method call might be just a block returning the last-evaluated 3. But the lines around def begin(foo) remains mystery.

Does using curly braces go against the "Ruby way"?

I've been using Ruby for about two weeks, and I've not been programming for too terribly long, but I'm coming at the language from a C-style background (C++, C#, etc). Anyway - a good friend and mentor of mine was looking at some Ruby that I'd written the other day, and he told me that he'd smack me if he caught me using curly braces in Ruby again.
Well, I just found out about Builder yesterday, via this About.com article, and the example that they have posted uses curly braces. Is there a different way to do this, or do you have to use curly braces with Builder?
This may seem like a minor point, but I'm new to Ruby, and I don't want to let myself develop any bad habits. What do you guys think?
While some people go with "braces for one-liners, do-end for multi-liners", I personally find the following rule the most logical:
use do-end when your block has side-effects (typically, with each and related methods) and
use braces when your block is without side-effects (map, inject and alike)
This logic goes well with method chaining issue that Matt wrote about.
One benefit of this approach is that it is going to make you think about side-effects every time you write a block, and they are very important, although sometimes overlooked by coders with no functional programming background.
Another way to put it, without involving side-effects terminology would be:
use do-end for blocks that perform
use { and } for blocks that return
Here are couple of articles with more info:
http://onestepback.org/index.cgi/Tech/Ruby/BraceVsDoEnd.rdoc
http://talklikeaduck.denhaven2.com/2007/10/02/ruby-blocks-do-or-brace
Idiomatic ruby is
method_name {|param| param.do_something} # squigglies for one liners
# do/end for multi-line
method_name do |param|
param.do_something
end
One reason for this is for chaining, foo.map {|f| f.num}.reduce(0) {|memo, i| memo + i} looks nicer then hanging a method call off of an end like
foo.map do |f|
f.num
end.reduce(0) do |memo, i|
memo + i
end
There is just something strange about calling a method off of end, even though syntactically the two are equivalent.
The usual convention is { ... } blocks for one-liners and do ... end for multi-liners. I generally follow this convention but should I ever be king I think I would use do .. end more often.
An occasional issue with {} is that {} binds more tightly than do end so the only way to write a poetry-mode block for a method that also has parameters is to use do end, otherwise the block will be part of the parameter and will not be not passed directly to the method.
def f x
yield x
end
f 123 do |n| p n end # works
f 123 { |n| p n } # does not work
f(123) { |n| p n } # works, of course
Of course, if you wanted to attach a block to a parameter in poetry mode, then you win with {} followed by do end.
def g ; p ['g', yield] end
def f x; p ['f', yield] end
f g { 2 } do 3 end
["g", 2]
["f", 3]
Finally, and contrary to some of the advice you have received here, a ; is not needed before end.
"The Ruby way" doesn't advocate any specific style. If they didn't want you to have the option to use curly braces, it wouldn't be in the language. That said, conform to your team's coding style (if you're working with a team).
Most Ruby code I've seen uses end in place of curly braces, but I don't use Ruby so I can't say for sure that this is the preferred style. Ruby has more than one way of doing things -- you can use whichever way pleases you (within reason).

Why doesn't Ruby support i++ or i--​ (increment/decrement operators)?

The pre/post increment/decrement operator (++ and --) are pretty standard programing language syntax (for procedural and object-oriented languages, at least).
Why doesn't Ruby support them? I understand you could accomplish the same thing with += and -=, but it just seems oddly arbitrary to exclude something like that, especially since it's so concise and conventional.
Example:
i = 0 #=> 0
i += 1 #=> 1
i #=> 1
i++ #=> expect 2, but as far as I can tell,
#=> irb ignores the second + and waits for a second number to add to i
I understand Fixnum is immutable, but if += can just instanciate a new Fixnum and set it, why not do the same for ++?
Is consistency in assignments containing the = character the only reason for this, or am I missing something?
Here is how Matz(Yukihiro Matsumoto) explains it in an old thread:
Hi,
In message "[ruby-talk:02706] X++?"
on 00/05/10, Aleksi Niemelä <aleksi.niemela#cinnober.com> writes:
|I got an idea from http://www.pragprog.com:8080/rubyfaq/rubyfaq-5.html#ss5.3
|and thought to try. I didn't manage to make "auto(in|de)crement" working so
|could somebody help here? Does this contain some errors or is the idea
|wrong?
(1) ++ and -- are NOT reserved operator in Ruby.
(2) C's increment/decrement operators are in fact hidden assignment.
They affect variables, not objects. You cannot accomplish
assignment via method. Ruby uses +=/-= operator instead.
(3) self cannot be a target of assignment. In addition, altering
the value of integer 1 might cause severe confusion throughout
the program.
matz.
One reason is that up to now every assignment operator (i.e. an operator which changes a variable) has a = in it. If you add ++ and --, that's no longer the case.
Another reason is that the behavior of ++ and -- often confuse people. Case in point: The return value of i++ in your example would actually be 1, not 2 (the new value of i would be 2, however).
It's not conventional in OO languages. In fact, there is no ++ in Smalltalk, the language that coined the term "object-oriented programming" (and the language Ruby is most strongly influenced by). What you mean is that it's conventional in C and languages closely imitating C. Ruby does have a somewhat C-like syntax, but it isn't slavish in adhering to C traditions.
As for why it isn't in Ruby: Matz didn't want it. That's really the ultimate reason.
The reason no such thing exists in Smalltalk is because it's part of the language's overriding philosophy that assigning a variable is fundamentally a different kind of thing than sending a message to an object — it's on a different level. This thinking probably influenced Matz in designing Ruby.
It wouldn't be impossible to include it in Ruby — you could easily write a preprocessor that transforms all ++ into +=1. but evidently Matz didn't like the idea of an operator that did a "hidden assignment." It also seems a little strange to have an operator with a hidden integer operand inside of it. No other operator in the language works that way.
I think there's another reason: ++ in Ruby wouldn't be remotely useful as in C and its direct successors.
The reason being, the for keyword: while it's essential in C, it's mostly superfluous in Ruby. Most of the iteration in Ruby is done through Enumerable methods, such as each and map when iterating through some data structure, and Fixnum#times method, when you need to loop an exact number of times.
Actually, as far as I have seen, most of the time +=1 is used by people freshly migrated to Ruby from C-style languages.
In short, it's really questionable if methods ++ and -- would be used at all.
You can define a .+ self-increment operator:
class Variable
def initialize value = nil
#value = value
end
attr_accessor :value
def method_missing *args, &blk
#value.send(*args, &blk)
end
def to_s
#value.to_s
end
# pre-increment ".+" when x not present
def +(x = nil)
x ? #value + x : #value += 1
end
def -(x = nil)
x ? #value - x : #value -= 1
end
end
i = Variable.new 5
puts i #=> 5
# normal use of +
puts i + 4 #=> 9
puts i #=> 5
# incrementing
puts i.+ #=> 6
puts i #=> 6
More information on "class Variable" is available in "Class Variable to increment Fixnum objects".
I think Matz' reasoning for not liking them is that it actually replaces the variable with a new one.
ex:
a = SomeClass.new
def a.go
'hello'
end
# at this point, you can call a.go
# but if you did an a++
# that really means a = a + 1
# so you can no longer call a.go
# as you have lost your original
Now if somebody could convince him that it should just call #succ! or what not, that would make more sense, and avoid the problem. You can suggest it on ruby core.
And in the words of David Black from his book "The Well-Grounded Rubyist":
Some objects in Ruby are stored in variables as immediate values. These include
integers, symbols (which look like :this), and the special objects true, false, and
nil. When you assign one of these values to a variable (x = 1), the variable holds
the value itself, rather than a reference to it.
In practical terms, this doesn’t matter (and it will often be left as implied, rather than
spelled out repeatedly, in discussions of references and related topics in this book).
Ruby handles the dereferencing of object references automatically; you don’t have to
do any extra work to send a message to an object that contains, say, a reference to
a string, as opposed to an object that contains an immediate integer value.
But the immediate-value representation rule has a couple of interesting ramifications,
especially when it comes to integers. For one thing, any object that’s represented
as an immediate value is always exactly the same object, no matter how many
variables it’s assigned to. There’s only one object 100, only one object false, and
so on.
The immediate, unique nature of integer-bound variables is behind Ruby’s lack of
pre- and post-increment operators—which is to say, you can’t do this in Ruby:
x = 1
x++ # No such operator
The reason is that due to the immediate presence of 1 in x, x++ would be like 1++,
which means you’d be changing the number 1 to the number 2—and that makes
no sense.
Some objects in Ruby are stored in variables as immediate values. These include integers, symbols (which look like :this), and the special objects true, false, and nil. When you assign one of these values to a variable (x = 1), the variable holds the value itself, rather than a reference to it.
Any object that’s represented as an immediate value is always exactly the same object, no matter how many variables it’s assigned to. There’s only one object 100, only one object false, and so on.
The immediate, unique nature of integer-bound variables is behind Ruby’s lack of pre-and post-increment operators—which is to say, you can’t do this in Ruby:
x=1
x++ # No such operator
The reason is that due to the immediate presence of 1 in x, x++ would be like 1++, which means you’d be changing the number 1 to the number 2—and that makes no sense.
Couldn't this be achieved by adding a new method to the fixnum or Integer class?
$ ruby -e 'numb=1;puts numb.next'
returns 2
"Destructive" methods seem to be appended with ! to warn possible users, so adding a new method called next! would pretty much do what was requested ie.
$ ruby -e 'numb=1; numb.next!; puts numb'
returns 2 (since numb has been incremented)
Of course, the next! method would have to check that the object was an integer variable and not a real number, but this should be available.

Ruby's yield feature in relation to computer science

I recently discovered Ruby's blocks and yielding features, and I was wondering: where does this fit in terms of computer science theory? Is it a functional programming technique, or something more specific?
Ruby's yield is not an iterator like in C# and Python. yield itself is actually a really simple concept once you understand how blocks work in Ruby.
Yes, blocks are a functional programming feature, even though Ruby is not properly a functional language. In fact, Ruby uses the method lambda to create block objects, which is borrowed from Lisp's syntax for creating anonymous functions — which is what blocks are. From a computer science standpoint, Ruby's blocks (and Lisp's lambda functions) are closures. In Ruby, methods usually take only one block. (You can pass more, but it's awkward.)
The yield keyword in Ruby is just a way of calling a block that's been given to a method. These two examples are equivalent:
def with_log
output = yield # We're calling our block here with yield
puts "Returned value is #{output}"
end
def with_log(&stuff_to_do) # the & tells Ruby to convert into
# an object without calling lambda
output = stuff_to_do.call # We're explicitly calling the block here
puts "Returned value is #{output}"
end
In the first case, we're just assuming there's a block and say to call it. In the other, Ruby wraps the block in an object and passes it as an argument. The first is more efficient and readable, but they're effectively the same. You'd call either one like this:
with_log do
a = 5
other_num = gets.to_i
#my_var = a + other_num
end
And it would print the value that wound up getting assigned to #my_var. (OK, so that's a completely stupid function, but I think you get the idea.)
Blocks are used for a lot of things in Ruby. Almost every place you'd use a loop in a language like Java, it's replaced in Ruby with methods that take blocks. For example,
[1,2,3].each {|value| print value} # prints "123"
[1,2,3].map {|value| 2**value} # returns [2, 4, 8]
[1,2,3].reject {|value| value % 2 == 0} # returns [1, 3]
As Andrew noted, it's also commonly used for opening files and many other places. Basically anytime you have a standard function that could use some custom logic (like sorting an array or processing a file), you'll use a block. There are other uses too, but this answer is already so long I'm afraid it will cause heart attacks in readers with weaker constitutions. Hopefully this clears up the confusion on this topic.
There's more to yield and blocks than mere looping.
The series Enumerating enumerable has a series of things you can do with enumerations, such as asking if a statement is true for any member of a group, or if it's true for all the members, or searching for any or all members meeting a certain condition.
Blocks are also useful for variable scope. Rather than merely being convenient, it can help with good design. For example, the code
File.open("filename", "w") do |f|
f.puts "text"
end
ensures that the file stream is closed when you're finished with it, even if an exception occurs, and that the variable is out of scope once you're finished with it.
A casual google didn't come up with a good blog post about blocks and yields in ruby. I don't know why.
Response to comment:
I suspect it gets closed because of the block ending, not because the variable goes out of scope.
My understanding is that nothing special happens when the last variable pointing to an object goes out of scope, apart from that object being eligible for garbage collection. I don't know how to confirm this, though.
I can show that the file object gets closed before it gets garbage collected, which usually doesn't happen immediately. In the following example, you can see that a file object is closed in the second puts statement, but it hasn't been garbage collected.
g = nil
File.open("/dev/null") do |f|
puts f.inspect # #<File:/dev/null>
puts f.object_id # Some number like 70233884832420
g = f
end
puts g.inspect # #<File:/dev/null (closed)>
puts g.object_id # The exact same number as the one printed out above,
# indicating that g points to the exact same object that f pointed to
I think the yield statement originated from the CLU language. I always wonder if the character from Tron was named after CLU too....
I think 'coroutine' is the keyword you're looking for.
E.g. http://en.wikipedia.org/wiki/Yield
Yield in computing and information science:
in computer science, a point of return (and re-entry) of a coroutine

Resources