[SOLVED] [Ruby] Strange results when returning Enumerator from function
ProgrammingThis 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.
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.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
[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
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)
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?
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.
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.
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.