I am trying to create a keyword message style method, but I can't figure out how to access the Receiver from inside the method. I am sure this is simple, however I can't find the answer anywhere. What I am trying to implement is redundant, but I would still like to know how it works.
subst: i1 by: i2
^ self copyReplaceAll: i1 with: i2.
It would be called in the workspace as follows:
string1 := 'Lemon'.
string2 := 'm'.
string3 := 'ss'.
string1 subst: string2 by: string3.
Error msg: "MessageNotUnderstood: ByteString>>subst:by:"
All the method should do is replace every occurance of "m" in "Lemon" with "ss" to create "Lesson" (which copyReplaceAll already does). I can't figure out how to get string1 into the method. Any help would be greatly appreciated,
Thanks in advance!
In Smalltalk, methods are not freestanding things.
A method is an object's way to respond to a message send.
If the thing that receives the message knows how to respond to the message, it has a method of responding to the message. The message name is said to be in the object's message protocol.
So - every message has a receiver and a message name.
A keyword message will also have one or more arguments, with one keyword for each argument.
The flipside of this is that all methods are part of an object. They are stored within the object's Class definition, as either a Class method or an instance method.
(The sole exception is in the specific case of the anonymous objects called blocks. In these cases, the method is defined in a block definition).
Here is an example keyword message:
Transcript show: 'Hello World!'
It means "send the message
show: 'Hello World!'
to the receiverTranscript
". (Transcript is a window which displays system output. All graphical Smalltalk environments have a Transcript class).This message has three parts:
The left-most part is always the receiver. In this example, the receiver is
Transcript
.The message name is
show:
which has a single keyword,show:
The argument is
'Hello World'
(An even fuller explanation of
Transcript show: 'Hello World!'
can be found at [http://beginningtosmalltalk.blogspot.com/2015/11/hello-world.html]
An example keyword message with multiple keywords:
aByteString copyReplaceAll: i1 with: i2
The receiver is
aByteString
, an instance of the ClassByteString
The message name is
copyReplaceAll:with:
It has two keywords,copyReplaceAll:
andwith:
.The arguments are
i1
andi2
.If
ByteString
Class, (or any Class above it in the Class hierarchy, likeString
), contains the method, then the message is in the object's protocol.string1 := 'Lemon' . string1 copyReplaceAll: i1 with: i2
If you want, you can add your code to
String
orByteString
as an additional method.subst: i1 by: i2
"Substitute all instances of substring i1 with string i2. Return the receiver"
^ self copyReplaceAll: i1 with: i2
Then it can be called in the workspace as follows:
string1 := 'Lemon'. string2 := 'm'. string3 := 'ss'. string1 subst: string2 by: string3
But
string1 subst: string2 by: string3
is not very different tostring1 copyReplaceAll: string2 with: string3
Another style point to note is that each keyword in a keyword message should be as descriptive and unambiguous as possible.
subst
could meansubstitute
orsubstring
The easiest way to add a method to a Class is by using the System Browser. Click on the Class in the System Browser, and a pro-forma method definition will appear in the edit pane.
Overtype it, and
Accept it
(on my system via right-click on a 2 or 3-button mouse, or the 'Ctrl-s' keyboard shortcut. Although mouse and key mappings can vary on different platforms).self
is the current object (i.e. the receiver).Please read (or at least skim) a tutorial to get the basics.
"MessageNotUnderstood: ByteString>>subst:by:"
This error means that you have not defined the message on ByteString. Either you have failed to actually define it anywhere, or you have defined it on the wrong class.