destructive! operations

N

Navindra Umanee

Hi,

Is it more efficient to use the destructive versions of functions in
Ruby? I know that in Lisp/Scheme destructive counterparts are usually
offered for efficiency reasons.

Can I assume that string.gsub! is preferable to string.gsub when I
know that the side-effect won't be affecting any other code?

I find the Ruby destructive operations sometimes inconvenient to use.
For example strip! might return null where strip would return a
string. However, if it's more efficient, I'd rather use the
destructive version.

Thanks,
Navin.
 
Y

Yukihiro Matsumoto

Hi

In message "Re: destructive! operations"

|Is it more efficient to use the destructive versions of functions in
|Ruby? I know that in Lisp/Scheme destructive counterparts are usually
|offered for efficiency reasons.
|
|Can I assume that string.gsub! is preferable to string.gsub when I
|know that the side-effect won't be affecting any other code?

Although most (not all) of bang methods are more efficient than their
counterparts, I discourage the use of them unless the performance is
really problem. "Premature optimization is the source of all evil".

matz.
 
R

Robert Klemme

Yukihiro Matsumoto said:
Hi

In message "Re: destructive! operations"
on Sun, 20 Feb 2005 17:22:34 +0900, Navindra Umanee

|Is it more efficient to use the destructive versions of functions in
|Ruby? I know that in Lisp/Scheme destructive counterparts are usually
|offered for efficiency reasons.
|
|Can I assume that string.gsub! is preferable to string.gsub when I
|know that the side-effect won't be affecting any other code?

Although most (not all) of bang methods are more efficient than their
counterparts, I discourage the use of them unless the performance is
really problem. "Premature optimization is the source of all evil".

Although I agree to the latter statement, I beg to differ on the general
remark - at least a bit. I often use this

while ( line = gets )
line.chomp!
# work with line
end

because I know it's going to be potentially invoked often - even in scripts
that are likely to run only on small input files. But for large files where
not every line is processed it easily divides the number of instances
created by a factor of 2.

Kind regards

robert
 
C

Caio Tiago Oliveira

Robert Klemme, 20/2/2005 12:04:
Although I agree to the latter statement, I beg to differ on the general
remark - at least a bit. I often use this

while ( line = gets )
line.chomp!
# work with line
end

because I know it's going to be potentially invoked often - even in
scripts that are likely to run only on small input files. But for large
files where not every line is processed it easily divides the number of
instances created by a factor of 2.

Bad example:

while ( line = gets.chomp )
# work with line
end
 
A

Alexander Kellett

Bad example:

while ( line = gets.chomp )
# work with line
end

unless ruby cow's the string and
the copy just has a truncating length,
then this requires copying of the line.

Alex
 
J

James Edward Gray II

Bad example:

while ( line = gets.chomp )
# work with line
end

gets() returns a String or nil. nil does not support chomp(). When
the chomp() is inside the while loop, this isn't an issue.

James Edward Gray II
 
N

Navindra Umanee

James Edward Gray II said:
gets() returns a String or nil. nil does not support chomp(). When
the chomp() is inside the while loop, this isn't an issue.

Often think it would be nice if "" and 0 were treated like nil. Such
functions could then return "". Heck, NilClass.to_s and NilClass.to_i
already return "" and 0 respectively.

Matz talks about premature optimizations. It looks like nil was made
this way for efficiency purposes! Can't say if it was premature
though. :)

Thanks for the answers!

Cheers,
Navin.
 
N

Navindra Umanee

Navindra Umanee said:
Often think it would be nice if "" and 0 were treated like nil. Such
functions could then return "". Heck, NilClass.to_s and NilClass.to_i
already return "" and 0 respectively.

"false" too..

Incidentally I tried to make "", 0 and false respond positively to
nil?. While they did, none of the boolean tests looked at nil? to
make their decision. I guess that's the optimized part.

Cheers,
Navin.
 
M

mark sparshatt

Navindra said:
Often think it would be nice if "" and 0 were treated like nil. Such
functions could then return "".

One problem with this suggestion that comes to mind is, what if there
are any blank lines in the file. then gets.chomp would return "" which
would cause the while loop to exit. Probably not what you want
 
N

Navindra Umanee

mark sparshatt said:
One problem with this suggestion that comes to mind is, what if there
are any blank lines in the file. then gets.chomp would return "" which
would cause the while loop to exit. Probably not what you want

Point. The chomp would make it not work here. There are many
situations where it could be elegant though.

Cheers,
Navin.
 
C

Csaba Henk

Often think it would be nice if "" and 0 were treated like nil. Such
functions could then return "". Heck, NilClass.to_s and NilClass.to_i
already return "" and 0 respectively.

Now, only false and nil drop you to the "else" branch of a conditional.
Certainly, there are cases when it' not the best behaviour, and you
have to write extra code to get the proper control flow when you test
against 0 and/or "".

If it were the other way around, and "", 0 (and [], {}) would lead to
the "else" branch as well, again, there would occur situations when it's
not the best behaviour and you'd need to write extra code to get things
right.

Now the question is: which of the two behaviours is the right thing more
often?

My experience is that the present way is the more optimal.

It's more cleaner as well. There is no intrinsic difference between ""
and "a", 0 and 1, [] and [1]. It would be artificial to force an
instance-sensitive policy when testing agains Strings, Integers and
Arrays.

Those guys who make a difference when using them in a conditional are
clearly separated into their respective cages (I mean, classes). That's
nice...

Csaba
 
A

Austin Ziegler

Often think it would be nice if "" and 0 were treated like nil. Such
functions could then return "". Heck, NilClass.to_s and NilClass.to_i
already return "" and 0 respectively.

I'm far happier that they aren't.

-austin
 
R

Robert Klemme

Austin Ziegler said:
I'm far happier that they aren't.

I didn't miss this "feature" either. I suspect that an unfinished
transition from Perl to Ruby makes people voice such whishes... :)

Kind regards

robert
 
A

Austin Ziegler

I didn't miss this "feature" either. I suspect that an unfinished
transition from Perl to Ruby makes people voice such whishes... :)

Or C++/Java to Ruby (not the "", but definitely the 0). I *have* been
bitten by 0/false problems in translations, but very few.

-austin
 
B

Brian Schröder

Sometimes, I'd like an "eating nil" that returns itself for each
method call, and is false.

Then, stuff like that would be possible

while line = gets.ignore_if_nil.chomp
...
end

Maybe just a crazy idea... :)

What would the ignore_if_nil call in your example do? Wouldn't the
above be equivalent to

while line = gets.chomp
...
end

Regards,

Brian
 
B

Bill Kelly

From: "Christian Neukirchen said:
Sometimes, I'd like an "eating nil" that returns itself for each
method call, and is false.

Then, stuff like that would be possible

while line = gets.ignore_if_nil.chomp
...
end

Maybe just a crazy idea... :)

class NilClass
def method_missing(meth_id, *args); self; end
end

?

:)

ObjectiveC's nil works this way.

The downside is you don't find out as early when you
received an unexpected nil, in situations where you
would have preferred to be notified.


Regards,

Bill
 
N

Navindra Umanee

Austin Ziegler said:
I'm far happier that they aren't.

Maybe what is more annoying, is this type of inconsistency:

irb(main):003:0> list[4..5]
=> nil
irb(main):004:0> list[0..3]
=> []

Ruby is riddled with these and IMHO it tends to make code that much
more ugly.

Cheers,
Navin.
 
A

Austin Ziegler

Austin Ziegler said:
I'm far happier that they aren't.
Maybe what is more annoying, is this type of inconsistency:

irb(main):003:0> list[4..5]
=> nil
irb(main):004:0> list[0..3]
=> []

Ruby is riddled with these and IMHO it tends to make code that much
more ugly.

That's not inconsistent; you're just not understanding. Matz posted
about this some time back and its a perfectly clear and consistent
way of working. Let's say you have an empty Array, 'a':

a = []
a[0] # nil
a[1] # nil

That's as expected. So why does this do something that you don't
expect?

a[0..3] # []
a[1..3] # nil

Well, it's easier to look at with a non-empty array. Let's try:

a = %w(a b c)
a[0] # a
a[1] # b
a[2] # c
a[3] # nil

Okay, that again is as expected. But where do the indexes point?
According to matz, the indexes are conceptually *between* elements.
Something like:

a b c
0^ 1^ 2^ 3^..

So when you start your range outside of the allowable indexes (and
the size of the array is an allowable, but empty, index), then
you'll get +nil+ from the #[] call. So for our above array, a[0..3]
produces the expected result, a[3..9] produces an empty array, and
a[4..9] produces nil.

It's regular. It's explained. It makes sense. It just doesn't work
like a P language. I doubt you'll find many experienced Ruby
programmers -- or novice Ruby programmers who don't expect Ruby to
act like a P language -- who are confused about this issue.

-austin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top