To_a

how come this works:

array = (1..8).to_a
puts array[1]

but this does not:

array = 1..8
array.to_a
puts array[1]

what do the () in the above example do that makes it work?

thanks

···

--
Posted via http://www.ruby-forum.com/.

The issue isn't with the parentheses, but with the behavior of the
#to_a method. #to_a does not modify its receiver. Instead, it builds
a new instance of Array and returns it. In the first example, you're
capturing the return value of #to_a and assigning it to the variable
"array". In the second, you're assigning a Range to the variable
"array", calling #to_a on it, and tossing the Array you get back on
the floor.

To make the second example work properly, you need to capture the
return value in a new variable and use that instead:

array = 1..8
result = array.to_a
puts result[1]

···

On Mar 15, 8:07 pm, Corey Konrad <0...@hush.com> wrote:

how come this works:

array = (1..8).to_a
puts array[1]

but this does not:

array = 1..8
array.to_a
puts array[1]

what do the () in the above example do that makes it work?

thanks

--
Posted viahttp://www.ruby-forum.com/.

Ash wrote:

···

On Mar 15, 8:07 pm, Corey Konrad <0...@hush.com> wrote:

what do the () in the above example do that makes it work?

thanks

--
Posted viahttp://www.ruby-forum.com/.

The issue isn't with the parentheses, but with the behavior of the
#to_a method. #to_a does not modify its receiver. Instead, it builds
a new instance of Array and returns it. In the first example, you're
capturing the return value of #to_a and assigning it to the variable
"array". In the second, you're assigning a Range to the variable
"array", calling #to_a on it, and tossing the Array you get back on
the floor.

To make the second example work properly, you need to capture the
return value in a new variable and use that instead:

array = 1..8
result = array.to_a
puts result[1]

i am not sure if i understand...so to_a doesnt actually transform the
range into an array it just creates a new array object. That still
doesnt explain why the first one using the () works though when i remove
the () it doesnt work. I dont know this stuff is really confusing. I
started learning ruby because i heard it was an easy and intuitive
language but it seems pretty difficult.

--
Posted via http://www.ruby-forum.com/\.

I think you understand fine, just take your time and take each step in turn. As you say, the code below works:

array = (1..8).to_a
puts array[1]

This makes a Range object from '(1..8)' and converts it to an Array using '.to_a'. This array is assigned to the variable 'array' and you can access it as normal.

The code below doesn't work:

array = 1..8
array.to_a
puts array[1]

This makes a Range object from '1..8' and assigns it to 'array'. You then create a new Array using 'array.to_a' but do not assign it to anything ('array' is still a Range). This means the final statement doesn't work.

From your second post it looks like you tried:

array = 1..8.to_a
puts array[1]

This doesn't work because you are asking for a Range constructed from '1' to '8.to_a'. I.e a Range from the Integer 1 to the Array '[8]'. This is an invalid Range. The parentheses in the first example ensure that the Range is constructed first and then the '.to_a' method is called on that. Essentially the method call '.to_a' takes precedence over the Range operator '..'.

Hope that helps.

Alex Gutteridge

Bioinformatics Center
Kyoto University

···

On 16 Mar 2007, at 09:33, Corey Konrad wrote:

Ash wrote:

On Mar 15, 8:07 pm, Corey Konrad <0...@hush.com> wrote:

what do the () in the above example do that makes it work?

thanks

--
Posted viahttp://www.ruby-forum.com/.

The issue isn't with the parentheses, but with the behavior of the
#to_a method. #to_a does not modify its receiver. Instead, it builds
a new instance of Array and returns it. In the first example, you're
capturing the return value of #to_a and assigning it to the variable
"array". In the second, you're assigning a Range to the variable
"array", calling #to_a on it, and tossing the Array you get back on
the floor.

To make the second example work properly, you need to capture the
return value in a new variable and use that instead:

array = 1..8
result = array.to_a
puts result[1]

i am not sure if i understand...so to_a doesnt actually transform the
range into an array it just creates a new array object. That still
doesnt explain why the first one using the () works though when i remove
the () it doesnt work. I dont know this stuff is really confusing. I
started learning ruby because i heard it was an easy and intuitive
language but it seems pretty difficult.

--
Posted via http://www.ruby-forum.com/\.

You're getting closer. It's correct that #to_a does not transform the
range into an array. In Ruby, methods that change the object they're
called on are usually marked with a !, like #sort! on Array (sorts the
array in place) or #capitalize! on String (uppercases the first letter
in place). Otherwise you can usually expect to get a new object back.

Here's a snippet that uses () to build the array but still doesn't
work:

array = (1..8) # Create a Range object, give it the name "array"
array.to_a # Call the method "to_a" on the Range, get back an
Array, but
                  # don't put it anywhere
puts array[1] # Message not understood, because "array" is the
original Range.

It just occurred to me that you might also be confused about what's
happening in the
first line of your working example.

array = (1..8).to_a

The assignment to "array" is done _last_. So this reads as "Create a
new Range from 1 to 8, send it the message 'to_a', then store the
result of all of that in 'array'", not "Create a new Range from 1 to
8, store that in 'array', then send it the message 'to_a'".

Just out of curiosity, is this your first programming language, or if
not what is your background? The issues you're encountering are
things that you'll run into in many languages, Ruby just isn't quite
as verbose in having them :slight_smile:

···

On Mar 15, 8:33 pm, Corey Konrad <0...@hush.com> wrote:

Ash wrote:
> On Mar 15, 8:07 pm, Corey Konrad <0...@hush.com> wrote:

>> what do the () in the above example do that makes it work?

>> thanks

>> --
>> Posted viahttp://www.ruby-forum.com/.

> The issue isn't with the parentheses, but with the behavior of the
> #to_a method. #to_a does not modify its receiver. Instead, it builds
> a new instance of Array and returns it. In the first example, you're
> capturing the return value of #to_a and assigning it to the variable
> "array". In the second, you're assigning a Range to the variable
> "array", calling #to_a on it, and tossing the Array you get back on
> the floor.

> To make the second example work properly, you need to capture the
> return value in a new variable and use that instead:

> array = 1..8
> result = array.to_a
> puts result[1]

i am not sure if i understand...so to_a doesnt actually transform the
range into an array it just creates a new array object. That still
doesnt explain why the first one using the () works though when i remove
the () it doesnt work. I dont know this stuff is really confusing. I
started learning ruby because i heard it was an easy and intuitive
language but it seems pretty difficult.

--
Posted viahttp://www.ruby-forum.com/.

Alex Gutteridge wrote:

The issue isn't with the parentheses, but with the behavior of the

language but it seems pretty difficult.

--
Posted via http://www.ruby-forum.com/\.

I think you understand fine, just take your time and take each step
in turn. As you say, the code below works:

array = (1..8).to_a
puts array[1]

This makes a Range object from '(1..8)' and converts it to an Array
using '.to_a'. This array is assigned to the variable 'array' and you
can access it as normal.

The code below doesn't work:

array = 1..8
array.to_a
puts array[1]

This makes a Range object from '1..8' and assigns it to 'array'. You
then create a new Array using 'array.to_a' but do not assign it to
anything ('array' is still a Range). This means the final statement
doesn't work.

From your second post it looks like you tried:

array = 1..8.to_a
puts array[1]

This doesn't work because you are asking for a Range constructed from
'1' to '8.to_a'. I.e a Range from the Integer 1 to the Array '[8]'.
This is an invalid Range. The parentheses in the first example ensure
that the Range is constructed first and then the '.to_a' method is
called on that. Essentially the method call '.to_a' takes precedence
over the Range operator '..'.

Hope that helps.

Alex Gutteridge

Bioinformatics Center
Kyoto University

ok, yeah now i understand why the () are there i just didnt see that for
some reason.

See when i tried

array = 1..8
array.to_a
puts array[1]

my view was that i was creating a range and assigning it to array and
then taking that range in array and converting it to an array by using
array.to_a. I had no idea i was just creating a new array there is no
way to tell that from looking at it for me even now, to me that code
looks like i am transforming the range stored in array... into an array.
My view was that array.to_a meant, take the range stored in array and
convert it to an array but that isnt what its doing its just converting
the variable array into an empty array? I dont know i still feel like i
am missing something that is going on behind the scenes, learning ruby
as a first programming language kind of seems like learning short hand
english first instead of becoming fluent in english grammer.

···

On 16 Mar 2007, at 09:33, Corey Konrad wrote:

--
Posted via http://www.ruby-forum.com/\.

Ash wrote:

···

On Mar 15, 8:33 pm, Corey Konrad <0...@hush.com> wrote:

> The issue isn't with the parentheses, but with the behavior of the
> array = 1..8
--
Posted viahttp://www.ruby-forum.com/.

You're getting closer. It's correct that #to_a does not transform the
range into an array. In Ruby, methods that change the object they're
called on are usually marked with a !, like #sort! on Array (sorts the
array in place) or #capitalize! on String (uppercases the first letter
in place). Otherwise you can usually expect to get a new object back.

Here's a snippet that uses () to build the array but still doesn't
work:

array = (1..8) # Create a Range object, give it the name "array"
array.to_a # Call the method "to_a" on the Range, get back an
Array, but
                  # don't put it anywhere
puts array[1] # Message not understood, because "array" is the
original Range.

It just occurred to me that you might also be confused about what's
happening in the
first line of your working example.

array = (1..8).to_a

The assignment to "array" is done _last_. So this reads as "Create a
new Range from 1 to 8, send it the message 'to_a', then store the
result of all of that in 'array'", not "Create a new Range from 1 to
8, store that in 'array', then send it the message 'to_a'".

Just out of curiosity, is this your first programming language, or if
not what is your background? The issues you're encountering are
things that you'll run into in many languages, Ruby just isn't quite
as verbose in having them :slight_smile:

My background i have a degree in computer information systems and have
been studying things like this for going on 4 years now, i got a 3.12
gpa in school and i have studied the syntax of many languages but for
some reason i just cant ever seem to get anywhere with it, its getting
really frustrating and i am starting to think that maybe i am mentally
retarded literally.

--
Posted via http://www.ruby-forum.com/\.

I think more familiarity with object oriented programming concepts may
help you sort these things out. Even though from a non-OOP background
it may look like array.to_a is doing something to the array variable,
it's not. The .to_a in that is a "message" you send to the object,
"array". That object, then, does "to_a". It doesn't change itself --
it just uses "to_a" to give you an array version of itself.

In other words, "array" doesn't "change to a", it emits "to a", which
you can then capture somewhere.

Think of objects, generally speaking, as immutable things that do stuff
for you when you ask nicely. You can get around that with the
assignment operator and bang-punctuated methods, but in general you're
not changing the object. Instead, you're getting it to give you
something.

That's oversimplified in the extreme, and prone to error if taken too
literally, but in general that's why .to_a gives you a return value
rather than changing the object. Interestingly, this philosophy of OOP
also overlaps somewhat with the functional programming paradigm, which
is why many people think of Ruby as an excellent language as a stepping
stone to more-pure functional programming languages.

···

On Fri, Mar 16, 2007 at 09:57:43AM +0900, Corey Konrad wrote:

See when i tried

> array = 1..8
> array.to_a
> puts array[1]

my view was that i was creating a range and assigning it to array and
then taking that range in array and converting it to an array by using
array.to_a. I had no idea i was just creating a new array there is no
way to tell that from looking at it for me even now, to me that code
looks like i am transforming the range stored in array... into an array.
My view was that array.to_a meant, take the range stored in array and
convert it to an array but that isnt what its doing its just converting
the variable array into an empty array? I dont know i still feel like i
am missing something that is going on behind the scenes, learning ruby
as a first programming language kind of seems like learning short hand
english first instead of becoming fluent in english grammer.

--
CCD CopyWrite Chad Perrin [ http://ccd.apotheon.org ]
"The ability to quote is a serviceable
substitute for wit." - W. Somerset Maugham

Alex Gutteridge wrote:

[snip!]

See when i tried

array = 1..8
array.to_a
puts array[1]

my view was that i was creating a range and assigning it to array and
then taking that range in array and converting it to an array by using
array.to_a. I had no idea i was just creating a new array there is no
way to tell that from looking at it for me even now, to me that code
looks like i am transforming the range stored in array... into an array.
My view was that array.to_a meant, take the range stored in array and
convert it to an array but that isnt what its doing its just converting
the variable array into an empty array?

Not quite. It's converting the Range to an Array and giving it to you, but you don't tell it to do anything with the new Array.

array = array.to_a

is what you're missing here. Almost all standard Ruby methods work this way unless you see one with a '!' in the method name. They are 'non-destructive', so they don't effect the object you call them on. Instead, they give you a new object. For example, the 'compact' and compact!' methods in the Array class both remove nil elements from an Array, but they work slightly differently. Compare:

arr = [1,nil,2,3]
arr.compact
puts arr[1]

with

arr = [1,nil,2,3]
arr.compact!
puts arr[1]

Alex Gutteridge

Bioinformatics Center
Kyoto University

···

On 16 Mar 2007, at 09:57, Corey Konrad wrote:

ok, yeah now i understand why the () are there i just didnt see that for
some reason.

See when i tried

> array = 1..8
> array.to_a
> puts array[1]

my view was that i was creating a range and assigning it to array and
then taking that range in array and converting it to an array by using
array.to_a. I had no idea i was just creating a new array there is no
way to tell that from looking at it for me even now, to me that code
looks like i am transforming the range stored in array... into an array.
My view was that array.to_a meant, take the range stored in array and
convert it to an array but that isnt what its doing its just converting
the variable array into an empty array? I dont know i still feel like i
am missing something that is going on behind the scenes, learning ruby
as a first programming language kind of seems like learning short hand
english first instead of becoming fluent in english grammer.

Maybe using the variable name 'array' is tricking you into thinking it
actually is an array.
Try changing the variable name, look at the code and think about the
explanation that Alex gave you.

Try this.

#foo = 1..8
#foo.to_a
#puts foo[1]

foo = 1..8
p foo
x = foo.to_a
p x
puts x[1]

Harry

···

--

Japanese Ruby List Subjects in English

My favorite programming teacher in high school had a saying he probably used daily, "Man I hate computers." :wink:

It's really a different way of thinking that takes some getting use to. Don't be too hard on yourself. We all went through this adjustment period.

James Edward Gray II

···

On Mar 15, 2007, at 8:15 PM, Corey Konrad wrote:

Ash wrote:

On Mar 15, 8:33 pm, Corey Konrad <0...@hush.com> wrote:

The issue isn't with the parentheses, but with the behavior of the
array = 1..8

--
Posted viahttp://www.ruby-forum.com/.

You're getting closer. It's correct that #to_a does not transform the
range into an array. In Ruby, methods that change the object they're
called on are usually marked with a !, like #sort! on Array (sorts the
array in place) or #capitalize! on String (uppercases the first letter
in place). Otherwise you can usually expect to get a new object back.

Here's a snippet that uses () to build the array but still doesn't
work:

array = (1..8) # Create a Range object, give it the name "array"
array.to_a # Call the method "to_a" on the Range, get back an
Array, but
                  # don't put it anywhere
puts array[1] # Message not understood, because "array" is the
original Range.

It just occurred to me that you might also be confused about what's
happening in the
first line of your working example.

array = (1..8).to_a

The assignment to "array" is done _last_. So this reads as "Create a
new Range from 1 to 8, send it the message 'to_a', then store the
result of all of that in 'array'", not "Create a new Range from 1 to
8, store that in 'array', then send it the message 'to_a'".

Just out of curiosity, is this your first programming language, or if
not what is your background? The issues you're encountering are
things that you'll run into in many languages, Ruby just isn't quite
as verbose in having them :slight_smile:

My background i have a degree in computer information systems and have
been studying things like this for going on 4 years now, i got a 3.12
gpa in school and i have studied the syntax of many languages but for
some reason i just cant ever seem to get anywhere with it, its getting
really frustrating and i am starting to think that maybe i am mentally
retarded literally.

James Gray wrote:

called on are usually marked with a !, like #sort! on Array (sorts
array.to_a # Call the method "to_a" on the Range, get back an

My background i have a degree in computer information systems and have
been studying things like this for going on 4 years now, i got a 3.12
gpa in school and i have studied the syntax of many languages but for
some reason i just cant ever seem to get anywhere with it, its getting
really frustrating and i am starting to think that maybe i am mentally
retarded literally.

My favorite programming teacher in high school had a saying he
probably used daily, "Man I hate computers." :wink:

It's really a different way of thinking that takes some getting use
to. Don't be too hard on yourself. We all went through this
adjustment period.

James Edward Gray II

yeah i suppose, man i cant imagine learning C or assmembler or something
like that. i think i get this issue now though methods arent destructive
so i am not transforming the range object i am returning a new array
object and i have to put it someplace in order to use it. I think that
makes sense now.

Thanks alot for the help you guys i appreciate it, believe me there are
more questions coming lol.

···

On Mar 15, 2007, at 8:15 PM, Corey Konrad wrote:

--
Posted via http://www.ruby-forum.com/\.

It also of course depends on the method. That is why everyone said "most of the time"...
It is possible to write your own code where a method call/message could actually change the reciever object.
It just isn't usual in Ruby.
Also do understand that methods are often oversimplified in human language.
The truth is, we "send a message" to an object. The object is the "reciever". If the object knows what to do with that message (if it has the method inside) it will do it. Otherwise the Ruby interpreter (the runtime environment in any OOP language) will move up the responder chain, to the object's parent class/super class. We say it sends the message there. The message will continue being sent until it reaches the root object class or finds a responder.
Some of the specifics are different with different languages, and it can get pretty abstract, but it is always the same.