LinuxQuestions.org
Did you know LQ has a Linux Hardware Compatibility List?
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
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



Reply
 
Search this Thread
Old 12-30-2012, 02:13 PM   #1
Snark1994
Senior Member
 
Registered: Sep 2010
Location: Wales, UK
Distribution: Arch
Posts: 1,632
Blog Entries: 3

Rep: Reputation: 345Reputation: 345Reputation: 345Reputation: 345
[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,
 
Old 12-31-2012, 05:34 AM   #2
grail
Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 7,698

Rep: Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988
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.
 
Old 01-01-2013, 05:17 AM   #3
Snark1994
Senior Member
 
Registered: Sep 2010
Location: Wales, UK
Distribution: Arch
Posts: 1,632
Blog Entries: 3

Original Poster
Rep: Reputation: 345Reputation: 345Reputation: 345Reputation: 345
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,
 
Old 01-01-2013, 06:07 AM   #4
grail
Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 7,698

Rep: Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988
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)
 
Old 01-01-2013, 06:39 PM   #5
Snark1994
Senior Member
 
Registered: Sep 2010
Location: Wales, UK
Distribution: Arch
Posts: 1,632
Blog Entries: 3

Original Poster
Rep: Reputation: 345Reputation: 345Reputation: 345Reputation: 345
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,
 
Old 01-01-2013, 07:07 PM   #6
sundialsvcs
Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 5,455

Rep: Reputation: 1172Reputation: 1172Reputation: 1172Reputation: 1172Reputation: 1172Reputation: 1172Reputation: 1172Reputation: 1172Reputation: 1172
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.
Old 01-02-2013, 05:47 AM   #7
Snark1994
Senior Member
 
Registered: Sep 2010
Location: Wales, UK
Distribution: Arch
Posts: 1,632
Blog Entries: 3

Original Poster
Rep: Reputation: 345Reputation: 345Reputation: 345Reputation: 345
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
 
Old 01-02-2013, 09:26 AM   #8
grail
Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 7,698

Rep: Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988
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:
Code:
$test = get_enum
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.
Old 01-02-2013, 10:28 AM   #9
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian
Posts: 2,543

Rep: Reputation: 880Reputation: 880Reputation: 880Reputation: 880Reputation: 880Reputation: 880Reputation: 880
Quote:
Originally Posted by Snark1994 View Post
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.
Old 01-02-2013, 05:50 PM   #10
Snark1994
Senior Member
 
Registered: Sep 2010
Location: Wales, UK
Distribution: Arch
Posts: 1,632
Blog Entries: 3

Original Poster
Rep: Reputation: 345Reputation: 345Reputation: 345Reputation: 345
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!
 
  


Reply

Tags
enumerator, function, ruby


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
returning boolean from function ? cmosentine Programming 3 02-16-2012 11:27 AM
time() function not returning jiml8 Programming 5 04-09-2008 02:03 PM
File searching programs not returning expected results Shadow ZERO Linux - Software 3 07-26-2007 03:35 PM
getent not returning expected results anirbanz Linux - Software 0 01-10-2006 09:44 PM
Is LQ Google Search not returning proper results? Bruce Hill LQ Suggestions & Feedback 2 09-15-2004 09:45 PM


All times are GMT -5. The time now is 01:43 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration