Why do some methods names which replace the content in place doesn't have the "!" sign?

E

Eric Boucher

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,
 
H

Hal Fulton

Tim said:
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
 
D

dblack

Hi --

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?

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 [] :)

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


David

--
David A. Black ([email protected])
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
 
K

karl_brodowsky

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"
 
D

dblack

Hi --

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 ([email protected])
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
 
R

Robert Dober

------=_Part_15351_16964486.1143536749806
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Hi --

Hi,

I was wandering why some ruby methods which replaces the contents of it= s
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?

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 [] :)

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


David

--
David A. Black ([email protected])
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 on=
e
exception to that rule :))

--
Deux choses sont infinies : l'univers et la b=EAtise humaine ; en ce qui
concerne l'univers, je n'en ai pas acquis la certitude absolue.

- Albert Einstein

------=_Part_15351_16964486.1143536749806--
 
D

dblack

Hi --

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 :)

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 ([email protected])
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
 
R

Robert Dober

------=_Part_17232_10310181.1143550228856
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Hi --



I'm all for revolutionary moods, but I'm afraid that makes no sense at
all :)


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.


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 ;)
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 =3D at the end o=
f
method names
Try to use this method
class Bad; def a=3D; puts "very bad"; end; end
So "!", "?" do not have the same kind of impact than "=3D", not too much
orthogonal, is it?

Enforcement (late but never theless ) of "=3D" 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 fo=
r
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 ([email protected])
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=EAtise humaine ; en ce qui
concerne l'univers, je n'en ai pas acquis la certitude absolue.

- Albert Einstein

------=_Part_17232_10310181.1143550228856--
 
D

dblack

Hi --

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

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


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 ([email protected])
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
 
P

Peter Hickman

Robert said:
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.
* 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.
* 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.
* 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.
 
G

Gregory Seidman

[...]
} 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
 
M

Michael Ulm

Peter said:
Robert said:
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.

You are mistaken. Consider

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

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

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 Ulm
R&D Team
ISIS Information Systems Austria
tel: +43 2236 27551-219, fax: +43 2236 21081
e-mail: (e-mail address removed)
Visit our Website: www.isis-papyrus.com

---------------------------------------------------------------
This e-mail is only intended for the recipient and not legally
binding. Unauthorised use, publication, reproduction or
disclosure of the content of this e-mail is not permitted.
This email has been checked for known viruses, but ISIS accepts
no responsibility for malicious or inappropriate content.
---------------------------------------------------------------
 
P

Peter Hickman

Michael said:
Peter said:
Robert said:
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.

You are mistaken. Consider

a = [1, 2, 3]
a.delete(3)
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.
 
R

Robert Dober

------=_Part_18569_1483376.1143557306973
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

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 :(


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=
 
P

Peter Hickman

Gregory said:
[...]
} 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.
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?
} >* 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.
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.
 
D

dblack

J

john_sips_tea

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! ;)
 
G

Gregory Seidman

} >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.

It's a technicality. Consider strings. Their internals are under the hood,
so you claim that no instance variables are involved. This is not
technically accurate. Object state happens to be held in C variables rather
than Ruby variables (which are, of course, backed by C variables), but they
are most certainly instance variables. Are you trolling or do you actually
believe you are right?

} David
--Greg
 

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

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top