[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

str1 = str2 is not a copy?!?

Joe Ruby

11/2/2006 9:06:00 PM

I have:

File.foreach(data_file) do |line|
line.strip!

puts line

base_name = line

puts line

base_name.sub!('www.', '')
base_name.sub!(/\.\w+$/, '')

puts line
end

Which outputs:

www.domain.com
www.domain.com
domain

WHY is var line getting changed by operations on var base_name? Isn't
'base_name = line' supposed to create a copy? '=' in this case seems to
be acting like an alias or something.

BTW, is there a foreach function that automatically strips off the
newlines from line? Returning the record separators is silly.

Currently hating Ruby,
Joe

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

10 Answers

Jamey Cribbs

11/2/2006 9:12:00 PM

0

Joe Ruby MUDCRAP-CE wrote:
> I have:
>
> File.foreach(data_file) do |line|
> line.strip!
>
> puts line
>
> base_name = line
>
> puts line
>
> base_name.sub!('www.', '')
> base_name.sub!(/\.\w+$/, '')
>
> puts line
> end
>
> Which outputs:
>
> www.domain.com
> www.domain.com
> domain
>
> WHY is var line getting changed by operations on var base_name? Isn't
> 'base_name = line' supposed to create a copy? '=' in this case seems to
> be acting like an alias or something.
>
>
Nope. Now, you have two variables, base_name and line, referencing the
same object. Try:

base_name = line.dup
> BTW, is there a foreach function that automatically strips off the
> newlines from line? Returning the record separators is silly.
>
>
line.chomp!
> Currently hating Ruby,
>
Be a lover not a fighter! ;-)

Jamey

Confidentiality Notice: This email message, including any attachments, is for the sole use of the intended recipient(s) and may contain confidential and/or privileged information. If you are not the intended recipient(s), you are hereby notified that any dissemination, unauthorized review, use, disclosure or distribution of this email and any materials contained in any attachments is prohibited. If you receive this message in error, or are not the intended recipient(s), please immediately notify the sender by email and destroy all copies of the original message, including attachments.

Farrel Lifson

11/2/2006 9:13:00 PM

0

On 02/11/06, Joe Ruby MUDCRAP-CE <joeat303@yahoo.com> wrote:
> I have:
>
> File.foreach(data_file) do |line|
> line.strip!
>
> puts line
>
> base_name = line
>
> puts line
>
> base_name.sub!('www.', '')
> base_name.sub!(/\.\w+$/, '')
>
> puts line
> end
>
> Which outputs:
>
> www.domain.com
> www.domain.com
> domain
>
> WHY is var line getting changed by operations on var base_name? Isn't
> 'base_name = line' supposed to create a copy? '=' in this case seems to
> be acting like an alias or something.
>
> BTW, is there a foreach function that automatically strips off the
> newlines from line? Returning the record separators is silly.
>
> Currently hating Ruby,
> Joe
>
> --
> Posted via http://www.ruby-....
>
>

It doesn't create a copy, both variables reference the same object. If
you don't want to modify the original value use sub rather than gsub!

Farrel

Austin Ziegler

11/2/2006 9:16:00 PM

0

On 11/2/06, Joe Ruby MUDCRAP-CE <joeat303@yahoo.com> wrote:
> WHY is var line getting changed by operations on var base_name? Isn't
> 'base_name = line' supposed to create a copy? '=' in this case seems
> to be acting like an alias or something.

No, it isn't. You're not understanding Ruby variables and assignment.

Variables in Ruby aren't locations; they're names. Objects are the only
things that take up (meaningful) space.

Assignment doesn't copy.

> BTW, is there a foreach function that automatically strips off the
> newlines from line? Returning the record separators is silly.

No, it isn't silly. Sometimes, that's what people want. You should be
using #chomp or #chomp! to strip that (use #strip or #strip! if and only
if you want to remove whitespace from beginning and end of the line).

-austin
--
Austin Ziegler * halostatue@gmail.com * http://www.halo...
* austin@halostatue.ca * http://www.halo...feed/
* austin@zieglers.ca

snacktime

11/2/2006 9:17:00 PM

0

On 11/2/06, Joe Ruby MUDCRAP-CE <joeat303@yahoo.com> wrote:
> I have:
>
> File.foreach(data_file) do |line|
> line.strip!
>
> puts line
>
> base_name = line
>
> puts line
>
> base_name.sub!('www.', '')
> base_name.sub!(/\.\w+$/, '')
>
> puts line
> end
>
> Which outputs:
>
> www.domain.com
> www.domain.com
> domain
>
> WHY is var line getting changed by operations on var base_name? Isn't
> 'base_name = line' supposed to create a copy? '=' in this case seems to
> be acting like an alias or something.

As far as my understanding goes most assignments just copy object
references. Try something like base_name = line.clone.

Chris

Louis J Scoras

11/2/2006 9:27:00 PM

0

As has been pointed out, you are creating a new binding to the same
object. Where it can get tricky is with multiple value assignments:

array = ['you', 'loose.']
a, b = array

p [a,b]
p array

b = 'win!'
p array # Doh!!

x = array ; x[1] = 'win!'
p array # array has been changed



--
Lou.

Paul Lutus

11/2/2006 9:28:00 PM

0

Joe Ruby MUDCRAP-CE wrote:

/ ...

> WHY is var line getting changed by operations on var base_name?

Because in most cases, variable names contain references for the sake of
efficiency. To get the behavior you want, try:

base_name = "" + line

But this is by no means the best thing to do in a lot of cases.

> Isn't
> 'base_name = line' supposed to create a copy? '=' in this case seems to
> be acting like an alias or something.

That's because base_name is an alias or something.

> BTW, is there a foreach function that automatically strips off the
> newlines from line? Returning the record separators is silly.

Really? How do you split the records after not providing the record
separator character in the saved data?

In a tab-separated database, tabs separate fields, and linefeeds separate
records. Neither tabs nor linefeeds are allowed within the fields. If you
remove either the tabs or the linefeeds from the database, you destroy the
integrity of the database.

> Currently hating Ruby,

It's okay. At the moment, you don't know enough to make an informed judgment
about Ruby. When you do, you will like it.

--
Paul Lutus
http://www.ara...

dblack

11/2/2006 9:48:00 PM

0

Chris Gernon

11/2/2006 10:18:00 PM

0

Joe Ruby MUDCRAP-CE wrote:
> WHY is var line getting changed by operations on var base_name? Isn't
> 'base_name = line' supposed to create a copy? '=' in this case seems to
> be acting like an alias or something.

Yep. All variables in Ruby are actually references to objects ... so
using the = operator actually signifies "this variable now points at the
same object as that variable". What you want is probably either:

base_name = line.clone

or

base_name = String.new(line)

but it would probably make more sense to just create base_name at the
first operation where you want the two to be different - for example:

line.strip!
puts line

base_name = line.sub('www.', '')
base_name.sub!(/\.\w+$/, '')

puts line

> BTW, is there a foreach function that automatically strips off the
> newlines from line? Returning the record separators is silly.

Hmmm, not that I know of. However, I just want to mention that you
probably want String#chomp rather than String#strip, unless you actually
want to strip whitespace from the beginning of the string as well.

> Currently hating Ruby,
> Joe

Watch it - you may be in danger of losing your MUDCRAP certification ...
;)

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

David Vallner

11/2/2006 10:41:00 PM

0

Paul Lutus wrote:
> Joe Ruby MUDCRAP-CE wrote:
>> WHY is var line getting changed by operations on var base_name?
>
> Because in most cases, variable names contain references for the sake of
> efficiency.

And I'm guessing the sake of simplicity too. The Ruby basic data item
object is thus one-dimensional, objects hold data, and variables point
to objects. Contrasting with C, where either variables hold data, or
heap memory holds data, and variables point to heap memory, or (ye gods)
C++, where references add yet another dimension to the variable / data
relationship (and that you can override the behaviour to do something
else when a data item changes the way it's being referenced
arbitrarily), this is -much- simpler to understand (when learning as a
first system, not if used to a PHPesque ad-hoc mixture of behaviours),
and what's more important, it's easier to keep a single set of quirks to
watch out for when using other peoples' code, or designing reusable code
(e.g. to avoid clobbering a library's internal state, etc.); although it
-is- a net loss of language expressivity. Indeed, AFAIK, even the
predominant C++ practice is "pick pointers or references and stick with
them throughout your code" for the common case.

David Vallner

Gregory Brown

11/4/2006 12:15:00 AM

0

On 11/2/06, Louis J Scoras <louis.j.scoras@gmail.com> wrote:
> As has been pointed out, you are creating a new binding to the same
> object. Where it can get tricky is with multiple value assignments:
>
> array = ['you', 'loose.']
> a, b = array
>
> p [a,b]
> p array
>
> b = 'win!'
> p array # Doh!!
>
> x = array ; x[1] = 'win!'
> p array # array has been changed

I get the point of this example, but it's worth noting that you can
change the array via b if you just use String#replace

>> b.replace "win"
>> array
=> ["you", "win"]