Str1 = str2 is not a copy?!?

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:

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

Joe R. 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 …
:wink:

Joe R. MUDCRAP-CE wrote:

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! :wink:

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.

On 02/11/06, Joe R. MUDCRAP-CE [email protected] wrote:

domain


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

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

On 11/2/06, Joe R. MUDCRAP-CE [email protected] 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

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

On 11/2/06, Joe R. MUDCRAP-CE [email protected] wrote:

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

Joe R. 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.

Hi –

On Fri, 3 Nov 2006, Paul L. wrote:

Joe R. 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

You don’t have to resort to a workaround like that; you can do:

base_name = line.dup

David

Paul L. wrote:

Joe R. 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 V.

On 11/2/06, Louis J Scoras [email protected] wrote:

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”]