Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game. |
| Notices |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
 |
GNU/Linux Basic Guide
This 255-page guide will provide you with the keys to understand the philosophy of free software, teach you how to use and handle it, and give you the tools required to move easily in the world of GNU/Linux. Many users and administrators will be taking their first steps with this GNU/Linux Basic guide and it will show you how to approach and solve the problems you encounter.
Click Here to receive this Complete Guide absolutely free. |
|
 |
12-30-2012, 01:13 PM
|
#1
|
|
Senior Member
Registered: Sep 2010
Location: Wales, UK
Distribution: Arch
Posts: 1,624
|
[Ruby] Strange results when returning Enumerator from function
Hiya,
I hit a bug in one of my ruby scripts, and narrowed it down to this unexpected behaviour:
Code:
#!/usr/bin/env/ruby
def get_enum
numbers = [1,2,3,4,5,6]
return numbers.each
end
puts get_enum().inspect
get_enum do |num|
p num
end
puts "\n"+get_enum().each.inspect
get_enum.each do |num|
p num
end
prints
Code:
#<Enumerator: [1, 2, 3, 4, 5, 6]:each>
#<Enumerator: [1, 2, 3, 4, 5, 6]:each>
1
2
3
4
5
6
while I would expect it to print
Code:
#<Enumerator: [1, 2, 3, 4, 5, 6]:each>
1
2
3
4
5
6
#<Enumerator: [1, 2, 3, 4, 5, 6]:each>
1
2
3
4
5
6
(as calling .each() on an Enumerator just returns itself).
Does anyone have any idea why this is happening?
Thanks,
|
|
|
|
12-31-2012, 04:34 AM
|
#2
|
|
Guru
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 6,316
|
Looks correct to me Snark as you do not call each on your enumerator that you created, ie:
Code:
#!/usr/bin/env/ruby
def get_enum
numbers = [1,2,3,4,5,6]
return numbers.each
end
puts get_enum().inspect
get_enum.each do |num|
p num
end
The loop is never entered without this.
|
|
|
|
01-01-2013, 04:17 AM
|
#3
|
|
Senior Member
Registered: Sep 2010
Location: Wales, UK
Distribution: Arch
Posts: 1,624
Original Poster
|
Hm. But why doesn't it work with the Enumerator returned from the function? I would expect the behaviour I got if the function I had was
Code:
def get_enum
numbers = [1,2,3,4,5,6]
return numbers #not numbers.each
end
but I called '.each' on the array before returning it...
Or is that just not how it works?
Thanks,
|
|
|
|
01-01-2013, 05:07 AM
|
#4
|
|
Guru
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 6,316
|
What you now have is an array being returned. My simple solution to following the issue was to put the following line into the code:
Code:
puts get_enum.class
This then tells you that with 'each' on the return item you are now returning an enumerator, but without it you are returning an array.
Let me know if that makes sense?
Maybe also remember that as everything is an object, when you call get_enum.<whatever>, the <whatever> is called on the item being returned (sorry if that is obvious)
|
|
|
|
01-01-2013, 05:39 PM
|
#5
|
|
Senior Member
Registered: Sep 2010
Location: Wales, UK
Distribution: Arch
Posts: 1,624
Original Poster
|
I think I understand what you're saying, but if I do then we're talking at cross purposes!
Code:
$numbers = [1,2,3,4,5,6]
def get_enum
return $numbers.each
end
puts get_enum.class
prints "Enumerator" (what I would expect) and
Code:
$numbers = [1,2,3,4,5,6]
def get_array
return $numbers
end
puts get_array.class
prints "Array" (also what I would expect). However, I can run
Code:
$numbers = [1,2,3,4,5,6]
$numbers.each do |x|
p x
end
and get the numbers printed out (still what I would expect) but when I try
Code:
$numbers = [1,2,3,4,5,6]
def get_enum
return $numbers.each
end
get_enum do |x|
p x
end
I don't get the numbers. If I'm returning "$numbers.each" from "get_enum", why does it behave differently if I change "$numbers.each" to "get_enum" in the line which has "do |x|" in it?
Sorry if I've misunderstood what you said!
Thanks,
|
|
|
|
01-01-2013, 06:07 PM
|
#6
|
|
Senior Member
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 4,554
|
If you use a variable the "wrong" way, Ruby will try to do what you told it to do, even to the point of transmogrifying the variable into the sort of thing that's appropriate for what you tried to do. Don't put a "right" and "wrong" example back-to-back in either order; set up the situation twice cleanly. Welcome to dynamic typecasting.
|
|
|
1 members found this post helpful.
|
01-02-2013, 04:47 AM
|
#7
|
|
Senior Member
Registered: Sep 2010
Location: Wales, UK
Distribution: Arch
Posts: 1,624
Original Poster
|
And returning an enumerator is the "wrong" thing?
I see, this is a "feature" then  okay, I guess that's my question solved, more or less. Thanks grail and sundialsvcs for your time 
|
|
|
|
01-02-2013, 08:26 AM
|
#8
|
|
Guru
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 6,316
|
Quote:
|
If I'm returning "$numbers.each" from "get_enum", why does it behave differently if I change "$numbers.each" to "get_enum" in the line which has "do |x|" in it?
|
Maybe think of assigning your return to a new variable:
This now makes "$test" into an enumerator and to cycle over the items in an enumerator you need to call something like:
Code:
$test.each {|x| ... }
You would not simply call "$test" and expect it to perform a block, you still need a method, such as each, to perform the action.
Not sure if that helps anymore?
I would not say that you are using the variables the wrong way but you are expecting an action from a variable instead of using a method.
|
|
|
1 members found this post helpful.
|
01-02-2013, 09:28 AM
|
#9
|
|
Senior Member
Registered: Nov 2005
Distribution: Debian
Posts: 2,017
|
Quote:
Originally Posted by Snark1994
I don't get the numbers. If I'm returning "$numbers.each" from "get_enum", why does it behave differently if I change "$numbers.each" to "get_enum" in the line which has "do |x|" in it?
|
Calling each does something different depending on whether you pass a block or not. You're expecting the no-argument version to return a thing-which-expects-a-block (more formally, you think you've done a partial application), but actually it just returns the enumerator (i.e. it's a nop), so to actually enumerate you have to call "each" (again) with a block argument.
|
|
|
1 members found this post helpful.
|
01-02-2013, 04:50 PM
|
#10
|
|
Senior Member
Registered: Sep 2010
Location: Wales, UK
Distribution: Arch
Posts: 1,624
Original Poster
|
Ah, yes, I guess I had the haskell-ish idea that once I've called ".each" then I should just be able to stick it into a block and it would work.
Thanks, ntubski!
|
|
|
|
| Thread Tools |
Search this Thread |
|
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -5. The time now is 04:05 PM.
|
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|