I have Tcl 8.6 installed on my system. I am just trying some examples from TIP #257: Object Orientation for Tcl :
oo::object create foo
::foo
oo::define foo {method bar {} {puts "Hello, World!"}}
foo does not refer to a class
while evaluating {oo::define foo {method bar {} {puts "Hello, World!"}}}
I thought that I can just create an object without class, or what I'm doing wrong?
Use objdefine instead of define to work on objects.
Note that a class is an object, so when you work on the class itself you still use objdefine.
Some of the examples on the wiki (and one in the documentation for the Tcllib oo::util module) were written while TclOO was still taking shape and are not executable under the current definition of the system. Another problem is that some wiki pages describe clever workarounds for TclOO limitations that have since been eliminated and no longer need any workarounds, so if you're learning TclOO from the wiki you will be confused. If anyone knows a good, up-to-date tutorial, feel free to comment with links.
(I just remembered this book chapter. I haven't studied it in detail, but it did clear a couple of things up for me.)
Documentation: oo::define (also objdefine), oo::util package
Related
I prefer working with files that are less than 1000 lines long, so am thinking of breaking up some Erlang modules into more bite-sized pieces.
Is there a way of doing this without expanding the public API of my library?
What I mean is, any time there is a module, any user can do module:func_exported_from_the_module. The only way to really have something be private that I know of is to not export it from any module (and even then holes can be poked).
So if there is technically no way to accomplish what I'm looking for, is there a convention?
For example, there are no private methods in Python classes, but the convention is to use a leading _ in _my_private_method to mark it as private.
I accept that the answer may be, "no, you must have 4K LOC files."
The closest thing to a convention is to use edoc tags, like #private and #hidden.
From the docs:
#hidden
Marks the function so that it will not appear in the
documentation (even if "private" documentation is generated). Useful
for debug/test functions, etc. The content can be used as a comment;
it is ignored by EDoc.
#private
Marks the function as private (i.e., not part of the public
interface), so that it will not appear in the normal documentation.
(If "private" documentation is generated, the function will be
included.) Only useful for exported functions, e.g. entry points for
spawn. (Non-exported functions are always "private".) The content can
be used as a comment; it is ignored by EDoc.
Please note that this answer started as a comment to #legoscia's answer
Different visibilities for different methods is not currently supported.
The current convention, if you want to call it that way, is to have one (or several) 'facade' my_lib.erl module(s) that export the public API of your library/application. Calling any internal module of the library is playing with fire and should be avoided (call them at your own risk).
There are some very nice features in the BEAM VM that rely on being able to call exported functions from any module, such as
Callbacks (funs/anonymous funs), MFA, erlang:apply/3: The calling code does not need to know anything about the library, just that it's something that needs to be called
Behaviours such as gen_server need the previous point to work
Hot reloading: You can upgrade the bytecode of any module without stopping the VM. The code server inside the VM maintains at most two versions of the bytecode for any module, redirecting external calls (those with the Module:) to the most recent version and the internal calls to the current version. That's why you may see some ?MODULE: calls in long-running servers, to be able to upgrade the code
You'd be able to argue that these points'd be available with more fine-grained BEAM-oriented visibility levels, true. But I don't think it would solve anything that's not solved with the facade modules, and it'd complicate other parts of the VM/code a great deal.
Bonus
Something similar applies to records and opaque types, records only exist at compile time, and opaque types only at dialyzer time. Nothing stops you from accessing their internals anywhere, but you'll only find problems if you go that way:
You insert a new field in the record, suddenly, all your {record_name,...} = break
You use a library that returns an opaque_adt(), you know that it's a list and use like so. The library is upgraded to include the size of the list, so now opaque_adt() is a tuple() and chaos ensues
Only those functions that are specified in the -export attribute are visible to other modules i.e "public" functions. All other functions are private. If you have specified -compile(export_all) only then all functions in module are visible outside. It is not recommended to use -compile(export_all).
I don't know of any existing convention for Erlang, but why not adopt the Python convention? Let's say that "library-private" functions are prefixed with an underscore. You'll need to quote function names with single quotes for that to work:
-module(bar).
-export(['_my_private_function'/0]).
'_my_private_function'() ->
foo.
Then you can call it as:
> bar:'_my_private_function'().
foo
To me, that communicates clearly that I shouldn't be calling that function unless I know what I'm doing. (and probably not even then)
I'm trying to learn PyQt5 and I am finding it very difficult since I can't just guess what methods are available. I've just spent an entire week trying to find a method to simulate a button push. I eventually found the solution ( QPushButton.animateClick() ) only after stumbling across an example someone left out there (how did this person know this?). It's very difficult to develop without some reference to what's available for tools!
Riverbank has a version of what I'm looking for but it is not complete making it virtually useless.
pyqt5 being a qt5 binding has almost all the functionalities (there are minimal known incompatibilities) so the qt5 documentation: https://doc.qt.io/ is valid for pyqt5 except for small exceptions.
Although the target of the documentation is c++ the description of the classes and methods are generic, so they also validly apply for pyqt5, on the other hand many of the examples are written in c++ but the translation to python in many cases is trivial .
So to avoid doing a double task it seems that Riverbank Computing Limited only documents the exceptions indicated in the pyqt5 docs: https://www.riverbankcomputing.com/static/Docs/PyQt5/
The next part of my answer will propose tips to handle the Qt documentation.
The Qt documentation also has an easy to understand structure, for example let's analyze the QPushButton class (https://doc.qt.io/qt-5/qpushbutton.html):
At the top there is a table:
This table indicates how to include the class in a C++ project, how to add it to qmake, from which class it inherits, and which classes inherit from it. From the above, relevant information for PyQt5 can be extracted, such as to which sub-module the class belongs to: In this case we use QT += widgets that inform us that it belongs to the QtWidgets sub-module, in general if Qt += submodulefoo belongs to QtSubModuleFoo (camelcase)
If you want to know all the methods of the QPushButton class, you must use the "List of all members, including inherited members" link below the table, in this case the link will be https://doc.qt.io/qt-5/qpushbutton-members.html where is the complete list of all class methods, enumerations, etc.
Other tips to understand the conversion between Qt/C++ and PyQt5/Python are:
Some methods use pointers to receive information such as:
void QLayout::getContentsMargins(int *left, int *top, int *right, int *bottom) const
bool QProcess::startDetached(qint64 *pid = nullptr), etc
those transformed to PyQt5 as:
lay = QtWidgets.QXLayout()
left, top, right, bottom = lay.getContentsMargins()
process = QProcess()
# ...
ok, pid = process.startDetached()
Some methods collide with reserved words such as exec , raise, print, etc so to avoid incompatibilities, the underscore is added at the end: exec_, raise_, print_, etc
In Qt, the Q_SLOT and Q_SIGNAL that are translated into python are used through the #pyqtSlot and #pyqtSignal decorators.
In conclusion, my recommendation is that you use the Qt and PyQt5 documentation at the same time to know all the functionalities, in addition there are many Q&A in SO about translations from one language to another so you could learn from there.
The Qt documentation can also be consulted using the Qt Assistant tool.
The main PyQt5 documentation is on the official website:
https://www.riverbankcomputing.com/static/Docs/PyQt5/
But it's still incomplete, and most parts refer to the official Qt documentation:
https://doc.qt.io/qt-5/
While that's C++ oriented, consider that almost every module, class and function behave exactly in the same way as it does in python, so it's usually better to use that.
Consider that:
in the function lists you'll always see the returned type on the left of each function;
"void" means that the function returns None;
when overriding some existing method (expecially private and virtual), you always have to return the expected types listed for that function;
function arguments are usually written in the form [const] Type argName=default: you can usually ignore the "const" part (it's a C++ term), while the argName for keyword arguments might be different in PyQt;
some functions could have different names, since they're reserved on python (print, raise, etc); in those cases, an underscore is always appended;
some positional or keyword arguments might be different, or the return type signature might; that's because in C++ you can use a pointer to a variable as an argument, and the function will change that variable using the pointer (this is an oversimplification);
all "properties" are not python properties, and they are only accessible through their parenthesis functions, such as self.width() an self.setWidth();
some methods have different overrides, in some cases python has special cases with different arguments that are not available in C++, and viceversa; also, some methods don't exist at all in one case or the other;
My suggestion is to always use the official documentation, it's only a matter of habit to get used to the C++ references (and you'll see that it is educational too); whenever some doubt raises, check the PyQt documentation to see what's different and use the help command in the python shell.
I've got an embarrassingly simple question here. I'm a smalltalk newbie (I attempt to dabble with it every 5 years or so), and I've got Pharo 6.1 running. How do I go about finding the official standard library documentation? Especially for the compiler class? Things like the compile and evaluate methods? I don't see how to perform a search with the Help Browser, and the method comments in the compiler class are fairly terse and cryptic. I also don't see an obvious link to the standard library API documentation at: http://pharo.org/documentation. The books "Pharo by Example" and "Deep into Pharo" don't appear to cover that class either. I imagine the class is probably similar for Squeak and other smalltalks, so a link to their documentation for the compiler class could be helpful as well.
Thanks!
There are several classes that collaborate in the compilation of a method (or expression) and, given your interest in the subject, I'm tempted to stimulate you even further in their study and understanding.
Generally speaking, the main classes are the Scanner, the Parser, the Compiler and the Encoder. Depending on the dialect these may have slightly different names and implementations but the central idea remains the same.
The Scanner parses the stream of characters of the source code and produces a stream of tokens. These tokens are then parsed by the Parser, which transforms them into the nodes of the AST (Abstract Syntax Tree). Then the Compiler visits the nodes of the AST to analyze them semantically. Here all variable nodes are classified: method arguments, method temporaries, shared, block arguments, block temporaries, etc. It is during this analysis where all variables get bound in their corresponding scope. At this point the AST is no longer "abstract" as it has been annotated with binding information. Finally, the nodes are revisited to generate the literal frame and bytecodes of the compiled method.
Of course, there are lots of things I'm omitting from this summary (pragmas, block closures, etc.) but with these basic ideas in mind you should now be ready to debug a very simple example. For instance, start with
Object compile: 'm ^3'
to internalize the process.
After some stepping into and over, you will reach the first interesting piece of code which is the method OpalCompiler >> #compile. If we remove the error handling blocks this methods speaks for itself:
compile
| cm |
ast := self parse.
self doSemanticAnalysis.
self callPlugins.
cm := ast generate: self compilationContext compiledMethodTrailer
^cm
First we have the #parse message where the parse nodes are created. Then we have the semantic analysis I mentioned above and finally #generate: produces the encoding. You should debug each of these methods to understand the compilation process in depth. Given that you are dealing with a tree be prepared to navigate thru a lot of visitors.
Once you become familiar with the main ideas you may want to try more elaborated -yet simple- examples to see other objects entering the scene.
Here are some simple facts:
Evaluation in Smalltalk is available everywhere: in workspaces, in
the Transcript, in Browsers, inspectors, the debugger, etc.
Basically, if you are allowed to edit text, most likely you will
also be allowed to evaluate it.
There are 4 evaluation commands
Do it (evaluates without showing the answer)
Print it (evaluates and prints the answer next to the expression)
Inspect it (evaluates and opens an inspector on the result)
Debug it (opens a debugger so you can evaluate your expression step by step).
Your expression can contain any literal (numbers, arrays, strings, characters, etc.)
17 "valid expression"
Your expression can contain any message.
3 + 4.
'Hello world' size.
1 bitShift: 28
Your expression can use any Global variable
Object new.
Smalltalk compiler
Your expression can reference self, super, true, nil, false.
SharedRandom globalGenerator next < 0.2 ifTrue: [nil] ifFalse: [self]
Your expression can use any variables declared in the context of the pane where you are writing. For example:
If you are writing in a class browser, self will be bound to the current class
If you are writing in an inspector, self is bound to the object under inspection. You can also use its instances variables in the expression.
If you are in the debugger, your expression can reference self, the instance variables, message arguments, temporaries, etc.
Finally, if you are in a workspace (a.k.a. Playground), you can use any temporaries there, which will be automatically created and remembered, without you having to declare them.
As near as I can tell, there is no API documentation for the Pharo standard library, like you find with other programming languages. This seems to be confirmed on the Pharo User's mailing list: http://forum.world.st/Essential-Documentation-td4916861.html
...there is a draft version of the ANSI standard available: http://wiki.squeak.org/squeak/uploads/172/standard_v1_9-indexed.pdf
...but that doesn't seem to cover the compiler class.
I am learning Smalltalk using Pharo+Squeak. I try to use the Playground/Workspace as a console, and figure out how to do everything there. One thing I have not figured out yet is how to add a method to a class.
Let's say I create a Cat class
Object subclass: #Cat
instanceVariableNames: ''
classVariableNames: ''
package: 'User Defined'.
To add a method makeSound to Cat, I can find it in the System Browser
Cat browse.
and create a new makeSound method there
makeSound
"Make Cat object make sound."
Transcript show: 'Meow!'.
I can then instantiate Cat and send it a makeSound message
cat := Cat new.
cat makeSound.
and it Meow! will show on the Transcript stream as expected.
Now, I do not know how to do all of this using the "console". In the Pharo by Example book it is mentioned that the convention for referring to methods is using ClassName>>methodName, and there are code snippets that look like this (I am probably butchering it!)
Cat class>>makeSound
Transcript show: 'Meow!'.
It does not work when I type it in the Playground/Workspace.
This syntax is mostly used to insert methods into documents. It is not something that can be executed directly in the System Browser or in the Playground. For example take your method:
Cat>>makeSound
Transcript show: 'Meow!'.
This just tells the reader that the method makeSound is in the class Cat. It's not executable. And it should be Cat>>makeSound and not Cat class>>makeSound. The second indicates that the method is on the class side.
You can add a method to a class from the Workspace by compiling it:
Cat
compile: 'makeSound
"Make Cat object make sound."
Transcript show: ''Meow!''.'
classified: 'actions'.
You can also directly access the compiled method object from a class using the message>>: Cat>>#makeSound. Once you have this method object you can also execute it on an object:
(Cat>>#makeSound) valueWithReceiver: Cat new arguments: #().
If you use the "File Out" functionality and check the generated code, you will notice a syntax using exclamation marks. This is not the most readable syntax and is not meant to be read or written by humans.
Pharo, like Squeak, follows the Smalltalk-80 philosophy of taking advantage of the GUI to provide multiple tools, like the Playground, the Debugger, the Inspector and the System Browser, each providing a very specialized functionality. That's because Smalltalk (and some derived languages, like Self) is not simply about code, but objects and messages, and those can have multiple representations, usually visual ones.
The beauty of the thing is that everything is defined using this metaphor, including the environment tools. So you could easily change them to suit your development style, or install and use another one, like Calypso.
Even if you want to develop a more traditional script-style program, I suggest you try developing it using the System Browser, and resorting to the Playground only for some quick experimentation. Pharo is getting better at deploying "headless" applications so it won't be a problem.
If you are worried about Git, check Iceberg. It serializes your code in a mostly readable way so your diffs look nice on Github for example.
I'm using Pharo 5.0. In a couple of cases, I have found a limit or possibly a bug in an existing Pharo class (e.g., something in DBXTalk/Garage, or Regex-Core). I would like to be able to modify a selector or set of selectors that exist(s) in a class outside of my own project and make that part of my package.
I have found several instructions on how to create a new selector in an outside class and move that into my package (e.g., as shown in this tutorial). That's very cool. But in some cases I actually want to modify an existing selector in the outside class and have my copy of that selector override the one in the outside class when I use it. I don't wish to modify the existing 3rd party or Pharo pre-supplied package.
In GNU Smalltalk, I can do that just as a normal part of doing a class extend. For example:
Kernel.MatchingRegexResults extend [
at: anIndex [
"My updated version of the 'official' Kernel.MatchingRegexResults#at: selector"
"This is part of my package so overrides the 'official' version"
...
]
foo [
"My new foo selector"
]
]
How can I do this in Pharo 5.0? I've done quite a bit of searching but couldn't find a means of doing it. The words "extend" or "override" do not appear in the Pharo by Example and Deep Into Pharo books.
Please note that, in addition to what Milan Vavra wrote, every method in a protocol named *YourPackage-(something) will belong to the package YourPackage, regardless of the package that the class belongs to. At least in Squeak, there is the convention to put methods overridden like this in the *YourPackage-override protocol. Pharo probably has a similar naming convention. The Move to package feature moves the method to such a "starred" protocol.
However, it is discouraged to use such overrides because you cannot have two packages provide an implementation for the same method simultaneously. Monticello will try to preserve both the original method and the overriding method (see senders of PackageInfo>>isOverrideCategory:), but it's still possible that your override method will be overridden by updates to its original package or you will miss updates to the original method, possibly breaking things.
The "Right Way" is to refactor the original method in the original package to make its behavior more easily customizable.
The code in GNU Smalltalk syntax
Kernel.MatchingRegexResults extend [
at: anIndex [
"method body"
]
foo [
"My new foo selector"
]
]
would look like this
!MatchingRegexResults methodsFor: 'protocol'!
at: anIndex
"method body"
!
foo
"My new foo selector"
! !
in a Pharo change set that can be filed in from File Browser.
But please note that in both cases, GNU Smalltalk and Pharo Smalltalk, you are actually replacing the original version of the method in that class.
In GNU Smalltalk you might not be accustomed to saving the image and hence you might think that the extend syntax does not modify the original method in the original class.
Actually it does exactly that.
With GNU Smalltalk you typically start with the same old unmodified image each time you run gst.
This is because the default place for the image in GNU Smalltalk is not writable to the normal user. So gst reads the same read-only image each time, you modify it in-memory with class definitions and extensions, your modified image only lives temporarily while your program is running, and is discarded on program exit.