I am investigating Squeak Smalltalk. Somehow I defined an object that initializes and prints the initial value (the instructions for that were in homework). Then I had to define a method (getName), which I did, but I don't know what to do to call the method in the workspace.
To test initialization i used
a := Animal new.
Transcript show: a; cr.
But for anything more than that I just don't know what to do. I tried a getName and a.getName, and more. What is the right way?
Please, help! I don't even know what to Google.
In Smalltalk, you send a message to a receiver.
e.g.
Animal new sends the new message to Class Animal.
This is an example of a unary message.
Transcript show: a sends the show: message to Class Transcript, with an argument of a.
This is an example of a keyword message.
Transcript cr sends the message cr to Class Transcript.
This is another example of a unary message.
Transcript show: a ;
cr .
This is an example of a message cascade, where several messages in a row are sent to the same receiver.
In a message cascade, you only type the name of the receiver once, use ; to separate the remainders of each message.
Transcript show: a ;
cr .
In Smalltalk, keywords which have an argument must have a colon suffix.
The convention is that simple accessors use the same name as the instance variable they access; and an instance of Class Object will have a variable name of the form anObject.
So an instance variable named name would have a getter called name and a setter called name:
Conventionally, we'd then have:
anAnimal := Animal new.
Transcript show: anAnimal name ;
cr .
Here, we send the name message to anAnimal. It returns the name of anAnimal. As a unary message, it has higher precedence than the keyword message Transcript show: <something>, and so is evaluated first. The return from the anAnimal name message becomes the argument to the Transcript show: <something> message.
You can see this for yourself. In the Workspace, highlight anAnimal name and then click and choose 'Inspect it'. This will bring up an Inspector window, and it will show you the object returned by the anAnimal name message.
These answers may help you understand:
Explain a piece of Smalltalk code
Keyword messages in smalltalk
This article, Beginning to Smalltalk: Hello World, goes into it in a little more detail, using Transcript show: 'Hello World'.
Ok, i think i got it. It's indeed a getName, but such line has nothing to do with return value. So i used Transcript show: a getName; cr. And it worked! Transcript appears to be an object too, and : is the way to pass arguments.
Related
I'm a newbie to Ruby, and so far have found the explanations for ! a bit too technical.
Let's say we have the following:
print "What is your first name?"
first_name = gets.chomp.upcase!
puts "Hi, #{first_name}. How are you?"
What does the ! add to the method? Does it mean that every time I use #{first_name} in any subsequent strings, all the letters in the name will print in upper-case? How is the code affected if I leave ! out?
Please explain it in layman's terms if you can, as I'm still coming to grips with some of Ruby's technical jargon.
Thanks in advance.
Ruby method names may end in !. It doesn't do anything special by itself, but there is a convention on which methods have it (though it is not always consistent); thus, just learn the method String#upcase! (and how it differs from String#upcase) on individual method-by-method basis, with the convention being a helpful reminder.
The convention is that the methods ending in ! are either dangerous, or change the object, or perform some other kind of change, or can raise an error where the other version wouldn't.
Specifically, String#upcase! changes the string it operates on. String#upcase makes a new string that is upcased.
foo = "test"
p(foo.upcase) # => "TEST"
p(foo) # => "test"
foo = "test"
p(foo.upcase!) # => "TEST"
p(foo) # => "TEST"
As described in comments, String#upcase! returns nil when no upcasing needs to happen, so you never want to reassign the return value of String#upcase! back to the same variable you tried to upcase!.
foo = "TEST"
p(foo.upcase!) # => nil
p(foo) # => "TEST"
RE: bang methods: see here
EDIT: "receiver" is the object receiving the message (i.e. method call). In foo.upcase!, the object in foo is the receiver. In "TEST".upcase, the string "TEST" is the receiver.
"in-place"` means the object itself is changed. The alternative is to create a new object that has the changes you want applied, with no change to the original object. For example, if you have a photo, cover the bottom half with a piece of paper and take a photo of that, you did a crude censorship by creating a new photo that is missing the lower half (but the original still exists). If you splat paint on the original photo, you censored it "in place".
What does the ! add to the method?
Nothing. The ! is simply part of the message name, just like the u, the p, the c, the a, the s, and the e are. It does not change anything about the message.
How is the code affected if I leave ! out?
Then you are simply sending a different message.
There is absolutely no difference whatsoever between upcase and upcase! or between foo and bar. They are just message names. If you write foo, then you send message foo, if you write bar, then you send message bar, if you write upcase, then you send message upcase (which in your case will be dispatched to the method String#upcase), if you write upcase!, then you send message upcase! (which in your case will be dispatched to the method String#upcase!).
There is absolutely nothing special about message names ending in !, just like there is absolutely nothing special about message names ending in ?, just like there is absolutely nothing special about message names ending in a or b or c.
There are, however, some conventions. In particular, the convention is:
If you have a pair of methods that both do more or less the same thing, then the one that is more surprising is named with a !.
That's it. That is all there is to it.
For example, there are the methods Process::exit and Process::exit!. They both do the same thing (terminate the process), but one of them skips running the installed exit handlers.
Since they both do the same thing, they could both be named "exit", but of course, you can't have two methods with the same name (on the same receiver). Therefore, we need to somehow distinguish between the two. We could come up with a completely different name for one of the two, but that would also be annoying.
So, instead, we add a ! to one of the two methods. Now, the question is: which one of the two do we add the ! to? Based on our convention, the "more surprising" one should get the !. The Ruby developers chose the one which ignores the exit handlers, which I think is the right choice: the whole point of exit handlers is that they get run when you exit, so a method that exits without running the exit handlers is surprising, and therefore should be marked with a !.
Note that none of this has anything to do with "destructive" or "mutation". Process::exit! doesn't mutate anything and it doesn't destroy anything. Note also that we only use the ! to mark the more surprising method of a pair of methods. There should never be a method named foo! when there is not also a method named foo.
In particular, the fact that a method does not have a ! does not tell you anything about the method. And the only thing that a method that does have a ! tells you is that there are two methods, and you should probably check the documentation to make sure that you understand what these two methods do and what the "surprise" is that the ! is warning you about. That's it.
In Ruby, what is the difference of using "?" inside if condition?
if object.property
or
if object.property?
I found the usage of both of them in a method, without understanding the difference
Thanks a lot
? can be part of the function name. It is not a special operator if it comes at the end of a method name. Also ! can be part of the method name too. So what that line is doing is calling both object.property and object.property? methods.
What are the restrictions for method names in Ruby?
In Ruby, foo.bar is the syntax for a message send. It will first evaluate the expression foo (which is either dereferencing a local variable or a receiverless message send to the implicit receiver self) and then send the message bar to the resulting object.
Once you know what message send in Ruby looks like, it is easy to see what object.property? does: It will first evaluate the expression object (which is either dereferencing a local variable or a receiverless message send to the implicit receiver self) and then send the message property? to the resulting object.
So, what is the difference between the two? Well, the first one sends the message property and the second one sends the message property?. This is no different than if the first one had been object.foo and the second one had been object.bar.
Method names ending in ? are typically used for predicate methods, i.e. for methods that ask a "Yes/No" question. A good example is Numeric#zero?.
I'm analyzing a block of code written in ruby.
I don't know the language and I need to understand an operation.
def restore
m = ObjectName.where(prop: User.where(email: 'admin#email.com').first.element_id).last
m.todo!
m.waiting!
...
end
what "m.todo!" and "m.waiting!" are doing?
I cannot understand if it is assigning a "true" value or a value that is the opposite of the current one like: m.todo = !m.todo
Thank you very much
! and ? are valid parts of a method name in Ruby. They don't have any special meaning, though ! is conventionally used for mutative or destructive actions, and ? is conventionally used for predicate methods.
In this example, there are two methods named todo! and waiting! being called - nothing fancier. If I had to guess, those are methods which simply perform a combined "update a state variable and save" operation (hence, mutative).
In Ruby, foo.bar is the syntax for a message send. It will first evaluate the expression foo (which is either dereferencing a local variable or a receiverless message send to the implicit receiver self) and then send the message bar to the resulting object.
Once you know what message send in Ruby looks like, it is easy to see what m.todo! does: It will first evaluate the expression m (which is either dereferencing a local variable or a receiverless message send to the implicit receiver self) and then send the message todo! to the resulting object.
Method names ending in ! are typically used to mark the "more surprising" of a pair of methods. So, if you have two Methods, both of which do similar things, then the one with the bang at the end is the "more surprising" one. A good example are Process::exit and Process::exit!. Both exit the currently running Ruby process, but the "normal" version (i.e. the one without the bang) runs the exit handlers normally, whereas the "surprising" Version exits immediately without running the exit handlers.
Note: there seems to be a lot of misunderstanding About the naming convention for bang methods. So, let me be clear:
Bang methods have absolutely nothing to do with mutation or destruction. It is simply about surprise. See the Process::exit! example above which has nothing to do with mutation.
Bang methods are always paired with a non-bang method. They mark the "more surprising" variant of a pair of methods. If there is no pair of methods, there is no bang. See, for example Array#collect!, which does have a bang because it is the more surprising variant of Array#collect, since it mutates its receiver; however, Array#append does not have a bang even though it also mutates its receiver because there is no corresponding "less surprising" method.
what "m.todo!" and "m.waiting!" are doing? I cannot understand if it is assigning a "true" value or a value that is the opposite of the current one like: m.todo = !m.todo
They do whatever the author of those methods wants. You will have to look that up in the documentation. Those are not methods of the Ruby core or standard library.
For Python 3.5 on Windows 7 64-bit and the psutil 5 library.
I'm confused as to how to properly access the name and pid information provided within each class 'psutil.Process' item returned by psutil.process_iter().
The following code returns a class 'generator' object:
import psutil
curProcesses = psutil.process_iter()
A simple loop outputs each class 'psutil.Process' object contained within that generator:
for eachProcess in curProcesses:
print(eachProcess)
OUTPUT:
psutil.Process(pid=0, name='System Idle Process')
psutil.Process(pid=4, name='System')
... and so on ...
Now here's where I'm getting confused.
IF I modify the previous loop as follows, THEN I'll get an integer pid and a string name.
for eachProcess in curProcesses:
# Observe the two different forms of access.
print(eachProcess.pid)
print(eachProcess.name())
OUTPUT:
0
System Idle Process
4
System
... and so on ...
The resulting integer and string are exactly what I want. However, after several experiments I can only get them IF:
eachProcess.pid is NOT followed by parentheses ala eachProcess.pid. (Adding parentheses produces a TypeError: 'int' object is not callable exception.)
eachProcess.name is followed by parentheses ala eachProcess.name(). (Removing the parentheses returns a bound method Process.name instead of the name as a string.)
Why do the two keyword-looking arguments pid and name behave differently? (I suspect I'm about to learn something very useful about Python 3 generator objects...)
There is not much to it really: pid is a read-only attribute (created with the #property decorator), and name() is a method, both of the Process class. Methods need parens to be called in order to return data, while attributes are accessed without them. This bit of documentation might be helpful. Also, if you find it helpful, you can see the difference in implementation between name() and pid.
As far as why pid is a read-only attribute of Process, while a method name() needs to be called in order to get the process name, I am not sure. In fact, pid appears to be the only read-only attrubute on the process class, while all other information about the process instance is retrieved through method calls. Personally it seems inconsistent/non-standard to do it this way, but I assume that there is a good reason for this choice. I assume the main reason is so the PID cannot be changed accidentally since it is a crucial component. If the PID were a method instead of a read-only attribute, then eachProcess.pid = 123 in your loop would change the method to the int 123, while the way it currently is, this attempted reassignment will raise an error instead, so that the PID is protected in a sense, while eachProcess.name = 'foo' will probably go by without raising an error.
Also, note that while they may look like keyword arguments in the way they appear in the string representations of Process class instances, name() and pid are not keyword arguments (although pid can be passed as a keyword argument when creating a Process instance, but that is not what is happening here).
I made pid a class attribute / property mainly for consistency with subprocess.Popen.pid and multiprocessing.Process.pid stdlib modules (also threading.Thread.ident comes to mind).
Also, it's something which does not require any calculation (contrarily from name(), cmdline() etc.) and it never changes, so something read-only made more sense to me at the time.
It's a property rather than a mere attribute just to error out in case the user tries to change/set it.
I remember watching a Dave Thomas Ruby tutorial where he used a technique to make invalid method names still acceptable to the interpreter. For example, even though "case date" is an invalid method name since there is a space, in the tutorial his trick allowed that method to still work.
Unfortunately, I don't remember it, but this is my situation. I accept user input and convert it to a method, as shown:
def self.define_field(name, type)
class_eval <<-EOS
field :#{ name}, type: #{type}
EOS
end
The problem is if there is a space in the user input or another invalid character for a method name, I get the following error:
syntax error, unexpected tIDENTIFIER, expecting end-of-input
field :damage date, type: Date
How can I can allow for my dynamic method creation, yet allow users to enter any input they want?
Given your class X, you can generate a symbol that accepts the space character:
s = input.to_sym
and then call, for example, define_singleton_method on your class to define a singleton method:
X.define_singleton_method(s) do
...
end
And then you can use send to call that method on a class X's instance x:
x.send(input.to_sym [, args...])
You could try converting name to a symbol directly, not through eval.
[1] pry(main)> "damage date".to_sym
=> :"damage date"
But unless you have a real solid reason to need spaces, I would find another way. Just seems like a recipe for disaster.
No idea what Dave Thomas was talking about, but I wonder if he was discussing method_missing?
http://www.ruby-doc.org/core-2.1.5/BasicObject.html#method-i-method_missing