Why do some methods names which replace the content in place


#1

Hi,

I was wandering why some ruby methods which replaces the contents of its
variable doesn’t follow the rules which say that when the method name
has a “!” symbol at the end, it means that its contents will be replace
in place. For example:

Array#replace instead of Array#replace!
Array#clear instead of Array#clear!

Is it because the name really mean what it mean? Maybe am I all wrong?

Thanks,


#2

Eric B. wrote:

Is it because the name really mean what it mean? Maybe am I all wrong?

Thanks,

Using a ! to mean “destructive” is not a hard-and-fast rule. Usually
(but not always) it’s used when there are a pair of methods with the
same name, one destructive and one not. If there is only one method with
that name, such as the two examples you give, then adding the ! is not
particularly useful. But there are always exceptions.


#3

Tim H. wrote:

Eric B. wrote:

Is it because the name really mean what it mean? Maybe am I all wrong?

Using a ! to mean “destructive” is not a hard-and-fast rule. Usually
(but not always) it’s used when there are a pair of methods with the
same name, one destructive and one not. If there is only one method with
that name, such as the two examples you give, then adding the ! is not
particularly useful. But there are always exceptions.

The ! doesn’t even mean “destructive” really. It means “dangerous” or
“caution required.” In the core, there is only one instance of a non-
destructive bang method, but in my own code, I do like to make the
distinction more.

Hal


#4

Hi –

On Mon, 27 Mar 2006, Eric B. wrote:

Is it because the name really mean what it mean? Maybe am I all wrong?

See Tim and Hal’s responses. A further reflection on it: In cases
where it would make no sense for there to be a non-“dangerous” version
of the method, there’s no need for the method/method! pair. In the
case of #replace, it’s hard to imagine what it would mean to replace
the contents of an array without changing it. And in the case of
clear, a non-destructive version would just be the same as [] :slight_smile:

So yes, it’s because the name already implies the whole operation.

David


David A. Black (removed_email_address@domain.invalid)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! http://www.manning.com/books/black


#5

On Mar 26, 2006, at 6:39 PM, Hal F. wrote:

In the core, there is only one instance of a non-
destructive bang method…

Just curious, what is this method?

Thanks.

James Edward G. II


#6

It would make sense to have a pair replace and replace!.
For example for Strings, it could be imagined such methods myreplace
and myreplace!:
a=“abcd”
b=a.myreplace(‘a’, ‘b’)
puts(a) # => “abcd”
puts(b) # => “bbcd”
b=a.myreplace!(‘a’, ‘c’)
puts(a) # => “cbcd”
puts(b) # => “cbcd”


#7

James Edward G. II wrote:

On Mar 26, 2006, at 6:39 PM, Hal F. wrote:

In the core, there is only one instance of a non-
destructive bang method…

Just curious, what is this method?

exit!

:slight_smile:

H


#8

Hi –

On Tue, 28 Mar 2006, removed_email_address@domain.invalid wrote:

It would make sense to have a pair replace and replace!.
For example for Strings, it could be imagined such methods myreplace
and myreplace!:
a=“abcd”
b=a.myreplace(‘a’, ‘b’)
puts(a) # => “abcd”
puts(b) # => “bbcd”
b=a.myreplace!(‘a’, ‘c’)
puts(a) # => “cbcd”
puts(b) # => “cbcd”

That’s not what replace does, though. See sub and sub!

David


David A. Black (removed_email_address@domain.invalid)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! http://www.manning.com/books/black


#9

On 3/27/06, removed_email_address@domain.invalid removed_email_address@domain.invalid wrote:

in place. For example:
case of #replace, it’s hard to imagine what it would mean to replace
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! http://www.manning.com/books/black

I am in a revolutionary mood today.
So I will put it to extremes:

It is a shame that methods can be defined in ruby, that do not end in
“!”
and still can modify instance variables of the receiver! (pun intended)

Honestely I think that would be a nice thing to have and I never even
thaught about it, I really appreciate Eric’s view!

Cheers
Robert

BTW
If there are always exceptions it follows that there must exist at least
one
exception to that rule :))


Deux choses sont infinies : l’univers et la bêtise humaine ; en ce qui
concerne l’univers, je n’en ai pas acquis la certitude absolue.

  • Albert Einstein

#10

Hi –

On Tue, 28 Mar 2006, Robert D. wrote:

I am in a revolutionary mood today.
So I will put it to extremes:

It is a shame that methods can be defined in ruby, that do not end in “!”
and still can modify instance variables of the receiver! (pun intended)

I’m all for revolutionary moods, but I’m afraid that makes no sense at
all :slight_smile:

Instance variables are the object’s business. When you call a method,
you shouldn’t even have to know whether instance variables are
involved. Also, ! means “dangerous”, and there’s nothing inherently
dangerous about methods that use instance variables.

David


David A. Black (removed_email_address@domain.invalid)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! http://www.manning.com/books/black


#11

Hi –

On Tue, 28 Mar 2006, Robert D. wrote:

“!”
involved. Also, ! means “dangerous”, and there’s nothing inherently

Please define “dangerous”, I do not have the most remote idea what might be
dangerous, apart
of modifying state, which is “modifying instance variable”.

A lot of ! methods on container objects (including strings) modify
their receivers. Instance variables aren’t involved. These are cases
where it might matter to the caller whether the change is permanent or
not. With instance variables, it’s not the caller’s business.

David


David A. Black (removed_email_address@domain.invalid)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! http://www.manning.com/books/black


#12

On 3/28/06, removed_email_address@domain.invalid removed_email_address@domain.invalid wrote:

and still can modify instance variables of the receiver! (pun intended)

I’m all for revolutionary moods, but I’m afraid that makes no sense at
all :slight_smile:

Makes a lot of sense to me (seriously!!!)

Instance variables are the object’s business. When you call a method,

you shouldn’t even have to know whether instance variables are
involved. Also, ! means “dangerous”, and there’s nothing inherently

Please define “dangerous”, I do not have the most remote idea what might
be
dangerous, apart
of modifying state, which is “modifying instance variable”.

dangerous about methods that use instance variables.

David

I do not want to change Ruby, but the basic idea to have a clear
syntactic
definition of what is “read only” access and what is “write” access
seems
very appealing to me.

Please try to get out of the Ruby paradigm for that theoretical
discussion.
So tell my why it is a bad idea, if you think it is a bad idea.
It does not make sense, is not a reason, BTW :wink:
I will tell you why it is a good idea.

  • The first and most important reason is a practical one
    How great for debugging and maintenance of code, you will never have to
    examine methods not ending with ! if you are searching for the reason of
    some strange value.
    Look at a C++ developper, she will never have to look into methods
    declared
    with “const”, and
    do you really think Ruby should be outclassed by C++?
    And it would be much better than in C++ because the information is
    conveyed
    at declaration and at usage.

  • The second reason is that this is only the surface of the iceberg
    It will be a revolutonary concept, think about classes.
    Only classes with names ending in “!” can be subclassed.
    Or classes not ending with “!” will become unmodifiable as Java::String
    or
    python::string
    There are for sure much more ideas, and much better ideas, that will
    spring
    into the mind of
    much more informed people than your humble servant.

  • The third reason is that I always felt unsure of !,? and = at the end
    of
    method names
    Try to use this method
    class Bad; def a=; puts “very bad”; end; end
    So “!”, “?” do not have the same kind of impact than “=”, not too much
    orthogonal, is it?

Enforcement (late but never theless ) of “=” is already “rubyish”, why
should “!” (or “?”, please see below) not be?

  • Other, much less important reasons, include ease for tools, analyzers
    and
    just beacause it would make the language more expressive.
    I always found there should be a class Boolean in Ruby with
    class Boolean < Object…
    class TrueClass < Boolean …
    class FalseClass < Boolean

than we could e.g. assure that
a method ending in ? would return a Boolean.

Of course other syntactic measures could be taken, but ! just seems fine
for
right now.

Maybe nobody wants this in Ruby, still I think it is a good idea to
think
about concepts like this.

Cheers
Robert

David A. Black (removed_email_address@domain.invalid)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! http://www.manning.com/books/black


Deux choses sont infinies : l’univers et la bêtise humaine ; en ce qui
concerne l’univers, je n’en ai pas acquis la certitude absolue.

  • Albert Einstein

#13

On Tue, Mar 28, 2006 at 10:23:21PM +0900, Peter H. wrote:
} Robert D. wrote:
[…]
} Methods have nothing to do with “read only” and “write” access. I
don’t
} know where you got this concept from but it is clearly confusing you,
} discard the concept, it is hindering your understanding of what Ruby
is
} actually doing.
}
} >* The first and most important reason is a practical one How great
for
} >debugging and maintenance of code, you will never have to examine
} >methods not ending with ! if you are searching for the reason of some
} >strange value. Look at a C++ developper, she will never have to look
} >into methods declared with “const”, and do you really think Ruby
should
} >be outclassed by C++? And it would be much better than in C++ because
} >the information is conveyed at declaration and at usage.
}
} This doesn’t make the slightest bit of sense to me.

Have you programmed in C++? There is a great deal of value to the idea
of
const instances of objects which only allow const methods to be called
on
them. I’m not claiming that Ruby should necessarily support such a
thing,
but I can certainly understand the desire for it.

} >* The second reason is that this is only the surface of the iceberg
It
} >will be a revolutonary concept, think about classes. Only classes
with
} >names ending in “!” can be subclassed. Or classes not ending with “!”
} >will become unmodifiable as Java::String or python::string There are
for
} >sure much more ideas, and much better ideas, that will spring into
the
} >mind of much more informed people than your humble servant.
}
} Ruby is a dynamic language, thus you can change classes. In fact is it
a
} very powerful concept (revolutionary even). If you want B&D then go
ahead
} and use Java (by the way you can modify unmodifiable Java Strings) but
} the reason that people like Ruby is that they can get things done
without
} the language getting in the way.

I’m inclined to agree with this. In addition, if you really need a
class
that can’t be changed you can freeze it; preventing subclassing can be
done
by making the class’s inherited method throw an exception. It’s
possible,
but probably undesirable. Note that there is absolutely nothing
revolutionary about Ruby, except possibly some of the software being
written in it. Ruby is an excellent implementation of a lot of good
programming language ideas (reflection/introspection, message sending,
anonymous blocks, OOP, mixins, dynamic typing, etc.), but there is
nothing
genuinely new about it.

} >* The third reason is that I always felt unsure of !,? and = at the
end
} >of method names Try to use this method class Bad; def a=; puts “very
} >bad”; end; end So “!”, “?” do not have the same kind of impact than
“=”,
} >not too much orthogonal, is it?
} >
} >Enforcement (late but never theless ) of “=” is already “rubyish”,
why
} >should “!” (or “?”, please see below) not be?
}
} I was going to answer this and your other points but frankly I get the
} impression that you don’t know enough about programming to understand
the
} answers. A lot of the converts to Ruby are programmers with many years
} experience who found, like myself, that they could get the job done in
} Ruby much easier than the various languages that they had been using
for
} years. That was the revolutionary concept and you seem to have missed
it
} completely.

There is no reason to be insulting. It is not unreasonable to expect
various non-alphanumeric characters at the end of a method name to mean
something to the parser, particularly when one of them (equals) actually
does. Furthermore, the question mark has a pretty clear semantic
meaning,
and almost all ruby code adheres to the convention well.

The bang (!), however, is used inconsistently. Its primary value seems
to
be distinguishing between methods that produce the same result, but the
one
without the bang produces the result in a returned copy whereas the
version
with the bang modifies the receiver to take on the resulting value
before
returning itself. Other uses muddy the waters, including the distinction
between save() and save!() in ActiveRecord models. So we call it
“dangerous” and define this vaguely to mean whatever the API author
considers dangerous. I consider the availability of the bang as an
allowed
character in a method name a noble, but largely failed, experiment.

–Greg


#14

Peter H. wrote:

that is the result of gsub(/[aeiou]/, ‘’) being applied to fred.
However fred.gsub!(/[aeiou]/, '
’) both returns a new object that is the
result of gsub(/[aeiou]/, ‘*’) being applied to fred AND modifies
fred.

You are mistaken. Consider

a = [1, 2, 3]
a.delete(3)
a # => [1, 2]

conveyed
at declaration and at usage.

This doesn’t make the slightest bit of sense to me.

It would if you knew C++. This is actually one of the more useful
features
of C++. If a method is declared ‘const’, the compiler ensures that it
does
not modify the instance variables of the object (unless you use really
deep
magic). This can be quite useful when debugging.

much more informed people than your humble servant.

Ruby is a dynamic language, thus you can change classes. In fact is it a
very powerful concept (revolutionary even). If you want B&D then go
ahead and use Java (by the way you can modify unmodifiable Java Strings)
but the reason that people like Ruby is that they can get things done
without the language getting in the way.

100% agreed.

should “!” (or “?”, please see below) not be?

I hope the condescending tone here was an accident. You too don’t know
everything (see above), and you too make mistakes (see above).

Regards,

Michael


Michael U.
R&D Team
ISIS Information Systems Austria
tel: +43 2236 27551-219, fax: +43 2236 21081
e-mail: removed_email_address@domain.invalid
Visit our Website: www.isis-papyrus.com


#15

Michael U. wrote:

Dangerous is any function that modifies the caller. Thus
a # => [1, 2]

I did not say that all methods that changed their caller had a !. I was
only explaining what the dangerous meant in reference to those classes
that had both a ! and non ! version of the method. Ruby is a little
inconsistent but the ! is a syntactic - not a rule, not enforced in any
way what so ever - convention (along with the ?) to make things clear
where they might be ambiguous. There are plenty of methods that alter
the caller but for gsub there are two versions of the same method and
the ! is there to point out which one is dangerous.

It would if you knew C++. This is actually one of the more useful
features
of C++. If a method is declared ‘const’, the compiler ensures that it
does
not modify the instance variables of the object (unless you use really
deep
magic). This can be quite useful when debugging.

I program in C++ (and Java and Perl) but fail to see how a feature from
a statically typed language would provide any benefit to a dynamic
language such as Ruby. Without even trying to work out how you would
hope to graft it on. I have never wanted for such a feature in Ruby but
I have wanted features from Ruby in other languages.

I hope the condescending tone here was an accident. You too don’t know
everything (see above), and you too make mistakes (see above).

I was cutting to the chase. I have read too many posts from people who
have only read a couple of articles on Ruby and think that they can fix
by making it more like C++, C, Java, Python, Perl, Visual Basic or
whatever they think they understand. Inexperienced programmers seem to
have a love of languages with many arcane and complex rules and when
they don’t find them they get all flustered and try and fix things
rather than try and understand how we could possibly develop anything
without them.


#16

Robert D. wrote:

Please define “dangerous”, I do not have the most remote idea what might be
dangerous, apart of modifying state, which is “modifying instance variable”.

Dangerous is any function that modifies the caller. Thus
fred.gsub(/[aeiou]/, ‘’) does not modify fred, it returns a new object
that is the result of gsub(/[aeiou]/, '
’) being applied to fred.
However fred.gsub!(/[aeiou]/, ‘’) both returns a new object that is the
result of gsub(/[aeiou]/, '
’) being applied to fred AND modifies
fred. Most methods in Rudy do not modify the caller but return a new
object. So anything that behaves differently / unexpectedly is
dangerous. In Ruby most (if not all) the classes that have ! methods
also have non ! version that does not alter the caller. This has been
explained before but I can’t remember which id the thread starts at. I
expect someone will be able to point this out.

I do not want to change Ruby, but the basic idea to have a clear syntactic
definition of what is “read only” access and what is “write” access seems
very appealing to me.

Methods have nothing to do with “read only” and “write” access. I don’t
know where you got this concept from but it is clearly confusing you,
discard the concept, it is hindering your understanding of what Ruby is
actually doing.

This doesn’t make the slightest bit of sense to me.

  • The second reason is that this is only the surface of the iceberg
    It will be a revolutonary concept, think about classes.
    Only classes with names ending in “!” can be subclassed.
    Or classes not ending with “!” will become unmodifiable as Java::String or
    python::string
    There are for sure much more ideas, and much better ideas, that will spring
    into the mind of
    much more informed people than your humble servant.

Ruby is a dynamic language, thus you can change classes. In fact is it a
very powerful concept (revolutionary even). If you want B&D then go
ahead and use Java (by the way you can modify unmodifiable Java Strings)
but the reason that people like Ruby is that they can get things done
without the language getting in the way.

I was going to answer this and your other points but frankly I get the
impression that you don’t know enough about programming to understand
the answers. A lot of the converts to Ruby are programmers with many
years experience who found, like myself, that they could get the job
done in Ruby much easier than the various languages that they had been
using for years. That was the revolutionary concept and you seem to have
missed it completely.


#17

Gregory S. wrote:

} >methods not ending with ! if you are searching for the reason of some
but I can certainly understand the desire for it.

I do program is C++ but, as I’ve said in another reply, I fail to see
how this is supposed to be of benefit in a dynamic language such as Ruby
and also how would you propose to implement it?

} answers. A lot of the converts to Ruby are programmers with many years

I always though of the ! as being a way of not having to come up with
yet another name for the same method. Image you have gsub and decide to
create the dangerous version, what do you call it that is easy to
remember, that wont be confused with gsub but will be associated with
gsub and can be applied to all similar dangerous versions. Sticking ! on
the end seems to be the sensible solution but I would not advocate
adding it to pop, delete and shift. There would be !s all over the place
which would make the code harder to read and there isn’t a non dangerous
version of pop, delete and shift anyway.

I was not being insulting, I honestly think that the poster does not
understand the issues. To understand a language you have to learn to use
it, once you do you get passed such superficial issues, such as the use
of ! on the end of a method name, they tend to become forgotten like the
lack of a prefix / postfix increment / decrement operator that people
coming from C++ and Java seem to stumble over as if it was a major
issue. Sure Lisp has lots of brackets and you have to indent things in
Python but once you learn the language these are no longer issues. When
people have problems with Lisp brackets, Python indents or Ruby !s they
haven’t even got as far as the syntax of the language let alone gained
an understanding of the heart of the language. Therefore I tend to be
abrupt with such people that then have the temerity to fix the
problems that is nothing more than their lack of experience.


#18

Hi –

On Tue, 28 Mar 2006, Robert D. wrote:

and how can one modify a receiver without modifying its instance variables,

str = “hello”
str.replace(“goodbye”)

I’ve changed str without any instance variables being involved. Same
with:

array = [1,2,3]
array.pop

and so forth.

David


David A. Black (removed_email_address@domain.invalid)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! http://www.manning.com/books/black


#19

I was cutting to the chase. I have read too many posts from
people who have only read a couple of articles on Ruby and
think that they can fix by making it more like C++, C, Java,
Python, Perl, Visual Basic or whatever they think they
understand.

Then as participants here, it’s our job to helpfully explain to
these folks, as best we can, how their suggestion may actually
not be a fix at all.

Geek points will be deducted for discourteousness! :wink:


#20

I am really sorry, this got way out of control.
I do have the impression that nobody understands anybody.
That is a pitty there were so nice concepts to be discussed, but I
really
feel that this discussion is not going well.

Maybe another time :frowning:

Just some clarifications

of course I find the “const” method of C++ a great thing, sorry if it
did
not come over
and how can one modify a receiver without modifying its instance
variables,
there is nowhere to go if we are caught by missunderstandings like this
one.
I am kind of %r{[sm]ad} about this, but that is my problem, you are
all
nice guys, that’s why I bail out of this, it is too close too my heart
and I
cannot make myself understood.

Regards and Regrets

Robert