new2net Posted July 20, 2011 Share Posted July 20, 2011 First I would like to say I have searched forums and read the documentation (ok I skimmed it...). While I have found a post similar to this one back in 2005, I wanted to address this issue again.My Question: What forms of encapsulation does AutoItv3 provide.List of Forms (that I know exist):BlockFunction [yes]ClassNested ClassPackageI have heard someone refer to a Class as a "chunk" in AutoItv3. I have never heard of this... but the example used scope resolution operators such as "::".List of forms explained:BlockA variable declared inside the block can not be seen from outside the block. If the variable needs to be reused, declare it before the block.Example: for(i = 0;i<10;i++) { String foo new String(foo != String ? ord(i) : foo + ord(i)); System.println(foo); } try { System.println(foo); // foo can not be seen.. exception occurs }Functionfunction foo(bar, baz) { //checks that bar and baz are real. pointless function return baz != NULL && bar != NULL; }Class & InterfacesA class is a collection of fields and functions. Some languages support operators such as final, abstract, static, public, constant, protected, private, synchronized.Modifiers can be used on the class itself, An example in poetic PHP:expandcollapse popup<?php interface DataBaseReflection { /** * Sets the primary key for the database related instance. * * @param (int) $identity * @throws InvalidArgumentException if $identity is not an unsigned integer. * @return (int) $identity */ public function setIdentity($identity); /** * Returns the primary key for the instance which invokes this method * as it relates to that instance's corresponding table. * * @throws NoIdentitySetException if there is no Identity set. * @return (int) number */ public function getIdentity(); } ?> <?php /** * DataBaseReflection manages the identities of objects in the application layer * in relation to the object's table identity (a unsigned INT auto_increment primary key). * If the table already has a primary key and does not use an unsigned integer, * implement ADataBaseReflection instead of extending this class. * * @package new2net.standard */ abstract class DataBaseUnsignedReflection implements DataBaseReflection { /** * The table's primary key (unsigned int). * @var (int) */ protected $identity; public final function setIdentity($identity) { if(is_numeric($identity) && $identity > 0) { $this->identity = $identity; return $this->identity; } else { throw new InvalidArgumentException(); } } public final function getIdentity() { if(is_int($this->identity) && $this->identity > 0) { return (int) $this->identity; } else { throw new NoIdentitySetException(); } } } ?><?php /** * Creating a User instance will force the end-user to log in using new2net's * CAS (central authentication system). Creating this instance will also attempt * to authorize the user with the database. * * @author new2net * @package net.phantomcircuit.standard */ class User extends DataBaseUnsignedReflection { //private parent::$identity ~~ User_ID ~~ unsigned Int /** * The username that my central authentication system returns; if this is empty or * null then the user has not been authenticated yet. * @var (string) */ private $username; /** * The user's first name. * @var (string) */ private $firstName; /** * The user's last name. * @var (string) */ private $lastName; /** * The user's email. * @var (string) */ private $email; /** * Roles is a combination of the valid user roles * See the User class for more information. * @var (int) */ private $roles; /** * True is the session has started, otherwise false. * @var (bool) */ private static $session = FALSE; const ROLE_APPLICANT = 1; // User.roles is a bitmask [--- or `SET()` in MySQL ---] .. const ROLE_REVIEWER = 2; // its just a 64bit integer really, nothing but 64 potential flags const ROLE_INTERVIEWER = 4; const ROLE_MANAGER = 8; public function __construct() { if(!self::$session) self::session_begin(); DATABASE::connect(); $this->username = $this->authenticate(); $this->authorize(); } final private function authenticate() { // sorry, don't want to share my CAS code. :) it sets $this->username when successful, otherwise redirects them to login w/ the CAS. } final private function authorize() { if (DEBUG::SANITY) DEBUG::SANITY(sprintf("Attempting to authorize %s.",$this->username)); $query = sprintf("SELECT User_ID, roles+0 as roles, first_name, last_name, email FROM `User` WHERE username = '%s';", mysql_real_escape_string(($this->getUserName()))); if(mysql_errno()) DATABASE::mysqlDebug(); $res = mysql_query($query); if (mysql_num_rows($res)) { $row = mysql_fetch_assoc($res); $this->setIdentity((int) $row['User_ID']); $this->roles = $row['roles']; $this->firstName = $row['first_name']; $this->lastName = $row['last_name']; $this->email = $row['email']; return true; } else { throw new NoSuchUserException(); } } /** * You can check a user against the User::ROLE_* constants, * you may also combine them using bitwise operators to check for multiple roles. * * @param (unsigned int) $role * @return (boolean) TRUE if they have the role, otherwise FALSE. */ public final function hasRole($role) { return (bool) ($this->roles & $role); //the parenthesis here are important } /** * Sends all roles and the user's corresponding roles to STDOUT. * return (void) */ public final function dumpRoles() { echo "<pre>", "Applicant....: ", (self::ROLE_APPLICANT & $this->roles ? "Yes" : "No") . "\n", "Reviewer.....: ", (self::ROLE_REVIEWER & $this->roles ? "Yes" : "No") . "\n", "Interviewer..: ", (self::ROLE_INTERVIEWER & $this->roles ? "Yes" : "No") . "\n", "Manager......: ", (self::ROLE_MANAGER & $this->roles ? "Yes" : "No") . "\n", "</pre>"; } /** * Starts the session with the configuration specified in the CONFIG class. * @return (bool) True if the session started, otherwise false. */ public static final function session_begin() { if(!self::$session) { session_save_path(CONFIG::SESSION_SAVE_PATH); ini_set('session.name', CONFIG::SESSION_NAME); ini_set('session.gc_probability', CONFIG::SESSION_GC_PROBABILITY); ini_set('session.gc_maxlifetime', CONFIG::SESSION_GC_MAX_LIFETIME); ini_set('session.cookie_lifetime', CONFIG::SESSION_COOKIE_LIFETIME); ini_set('session.cache_expire', CONFIG::SESSION_CACHE_EXPIRE); } self::$session = session_start(); if (DEBUG::SANITY) DEBUG::SANITY(self::$session ? "Session has started." : "Session failed to start!"); return (bool) self::$session; } /** * Returns the user's username. * @return (string) */ public final function getUserName() { return (string) $this->username; } /** * Returns the user's real name. * @return (string) - it may be empty if it has not been entered yet. */ public final function getRealName() { return (string) $this->firstName.' '.$this->lastName; } /** * Returns the user's first name. * @return (string) - it may be empty if it has not been entered yet. */ public final function getFirstName() { return (string) $this->firstName; } /** * Returns the user's last name. * @return (string) - it may be empty if it has not been entered yet. */ public final function getLastName() { return (string) $this->lastName; } /** * Returns the user's email. * @return (string) */ public final function getEmail() { return (string) $this->email; } /** * Add an entry into the access log */ public static function poppop() { DATABASE::connect(); @mysql_query(sprintf("INSERT INTO AccessLog (`user`,`ipAddress`,`url`,`agent`,`serializedSession`,`serializedServer`) VALUES ('%s','%s','%s','%s','%s','%s')", DATABASE::ESC(@$_SESSION['user']), DATABASE::ESC($_SERVER['REMOTE_ADDR']), DATABASE::ESC($_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']), DATABASE::ESC($_SERVER['HTTP_USER_AGENT']), DATABASE::ESC(serialize(@$_SESSION)), DATABASE::ESC(serialize($_SERVER)))); DATABASE::mysqlDebug(); } /** * Destroy's the user's session. * @return (bool) true if it worked, otherwise false... if false you have some server issues to work out */ public final function logout() { return (bool) session_destroy(); } } ?><?php Abstract class Viewer extends User implements SplSubject{} Final class Interviewer extends Viewer implements SplObserver{} class Admin extends User implements SplObserver{} final class Applicant extends User implements InnerIterator, SplSubject{} /** * A Reviewer has access to view and vote on preselected applications. * * @author new2net * @package net.phantomcircuit.internships */ Final class Reviewer extends Viewer implements SplObserver{ // Oh that's nice. I can reuse the same functions because both a reviewer, administrator, interviewer, and applicant are all users who log in. // well how can I make an instance identify itself?... easy, use $this->getIdentity(); That level of abstraction was handled immediately: /** * StdObject * } ?>So this really begs the question: "Why does anyone care?". Because you can create a powerful library / API / wrapper for lots of difficult jobs and then reuse it. This is important because copy + pasting code is not just really sloppy, but does not always achieve the result you expect, and can lead to an incredible amount of refactoring.A difficult problem can be looked at as a set of smaller problems, which have reusable solutions.Nested ClassesNot only can someone create a class, but they can create classes and interfaces insider other classes and interfaces! It's almost an art.Supported in (that I know of): Scala, Python, JavaJava Example of a Linked List. The nested classes are the Empty (SINGLETON), and Node classes. A LinkedList is useful for creating an unbound stack, balanced trees, binary trees, and very short lists. My implementation does not support mutating the list.expandcollapse popuppackage new2net; import new2net.LexicographicalComparator; import java.util.AbstractCollection; import java.util.Iterator; /** * @author new2net (irc.freenode.net) */ abstract class SchemeList<T> extends AbstractCollection<T> implements Comparable<T> { public interface Fun<T, T2> { T2 apply(T obj); } public interface Proc<T> { void apply(T obj); } private static class Node<T> extends SchemeList<T> { private T head; private SchemeList<T> tail; public Node(T head, SchemeList<T> tail) { this.head = head; this.tail = tail; } @Override public T head() { return head; } @Override public SchemeList<T> tail() { return tail; } @Override public int length() { return tail().length() + 1; } @Override public SchemeList<T> append(SchemeList<T> list) { return list == EMPTY ? this : new Node<T>(list.head(), append(list.tail())); } @Override public int size() { return length(); } //abstract public <T2> SchemeList<T2> map(Fun<T, T2> f); @Override public <T2> SchemeList<T2> map(Fun<T, T2> f) { return new Node<T2>(f.apply(head), tail.map(f)); } @Override public void forEach(Proc<T> f) { f.apply(head); tail.forEach(f); } @Override public String toString() { Iterator<T> toStringIterator = iterator(); StringBuffer tempString = new StringBuffer("("); while(toStringIterator.hasNext()) { tempString.append(toStringIterator.next() + " "); } tempString.deleteCharAt(tempString.length() - 1); return tempString + ")"; } @Override public int compareTo(T o) { return new LexicographicalComparator().compare(head.toString(), o.toString()); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((head == null) ? 0 : head.hashCode()); result = prime * result + ((tail == null) ? 0 : tail.hashCode()); return result; } @Override public boolean equals(Object obj) { if (!(obj instanceof Node)) return false; //this should work now that I know it's of type Node and not null return hashCode() == obj.hashCode(); } } private static class Empty<T> extends SchemeList<T> { @SuppressWarnings("serial") private static class Exception extends UnsupportedOperationException {} // default constructor -- nothing to construct @Override public T head() throws Exception { throw new Exception(); } @Override public SchemeList<T> tail() throws Exception { throw new Exception(); } @Override public SchemeList<T> append(SchemeList<T> list) { return list; } @Override public int length() { return 0; } @Override public String toString() { return "()"; } @Override public int size() { return length(); } @SuppressWarnings("unchecked") @Override public <T2> SchemeList<T2> map(Fun<T, T2> f) { return (SchemeList<T2>) this; } @Override public int compareTo(T o) { return new LexicographicalComparator().compare("", o.toString()); } @Override public boolean equals(Object obj) { // TODO Auto-generated method stub return false; } @Override public void forEach(Proc<T> f) {} } /** * @author RLa (irc.freenode.net #java) */ private static class SchemeListIterator<T> implements Iterator<T> { private SchemeList<T> list; public SchemeListIterator(SchemeList<T> list) { this.list = list; } @Override public boolean hasNext() { return list != EMPTY; } @Override public T next() { T head = list.head(); list = list.tail(); return head; } @Override public void remove() { throw new UnsupportedOperationException(); } } /** * This is the empty list. Use it to build new lists. All lists end with the * empty list. */ public static final SchemeList<?> EMPTY = emptyList(); /* what a freaking mess! stupid generics!!! */ private static final <T> SchemeList<T> emptyList() { return new Empty<T>(); } private SchemeList() {} // You must use the emptyList "EMPTY" abstract public boolean equals(Object obj); /** * @return The datum in the link list Node * @throws Exception * if the node is an empty list. */ abstract public T head(); /** * @return The node (if it exists) linked to the invoking node. * @throws Exception * if the node is the empty list. */ abstract public SchemeList<T> tail(); /** * returns the length of the list, 0 if the list is empty. * * @return the length of the list. */ abstract public int length(); abstract public String toString(); /** * Takes any object and links it to the end of the invoking list as a new * SchemeList Node with the object in the "head" of the list. * * @param obj * - any object * @return SchemeList */ public SchemeList<T> cons(T obj) { return new Node<T>(obj, this); } /** * Takes all of the nodes from the argument "list" and uses cons to link them * to the invoking list. * * @param list * SchemeList whos nodes will be attached to the invoking list. * @return SchemeList - a new list with the invoking lists nodes preceded by * the nodes in the list passed to append. */ abstract public SchemeList<T> append(SchemeList<T> list); /** * Applies an anonymous function to the invoking list, and returns a new * list (in the same order) with values processed by the anonymous function * Fun.apply(). * * @param f * - SchemeList.Fun.apply (an anonymous function) * @return - A list in the same order as the one which called map() */ abstract public <T2> SchemeList<T2> map(Fun<T, T2> f); /** * Goes through the list in order passing each SchemeList node as an argument * (Object) to an anonymous function SchemeList.Proc.apply(). * * Note that forEach() does not return any value, unlike map(). * * @param f * - SchemeList.Proc.apply (an anonymous function) */ abstract public void forEach(Proc<T> f); /** * Compares the parameter o to the current head using lexicographical ordering. * If the invoking list is empty, then the parameter o will be compared to an * empty string. * * @param o - The object to be compared * * @return -1 (o comes before the current list element), * 0 (o equals the current list element), * 1 (o comes after the current list element). * * @throws ClassCastException if the specified object's type prevents * it from being compared to this object. */ abstract public int compareTo(T o); @Override public final Iterator<T> iterator() { return new SchemeListIterator<T>(this); } }PackageA package is a set of code. One should also hope for documentation along with a package, although that doesn't always happen. Some packages might be "crypt", "cgi", "mysql", and so on. A package does not imply that classes are declared. It's intended to be scalable and reusable code.So, is there any OOP support in AutoItv3? Link to comment Share on other sites More sharing options...
AdmiralAlkex Posted July 20, 2011 Share Posted July 20, 2011 (edited) Hi and Welcome to the forums!!Block Nope, but you could get similar effect by using a function with a Local variable instead of the block.Function Class AutoItObject UDFNested Class Repeat previous answerPackage #include ?So, is there any OOP support in AutoItv3? Third time's the charm? Edited July 20, 2011 by AdmiralManHairAlkex .Some of my scripts: ShiftER, Codec-Control, Resolution switcher for HTC ShiftSome of my UDFs: SDL UDF, SetDefaultDllDirectories, Converting GDI+ Bitmap/Image to SDL Surface Link to comment Share on other sites More sharing options...
new2net Posted July 22, 2011 Author Share Posted July 22, 2011 (edited) I can not find any documentation for that code/package. Please advise Documentation as in "How to use this, what this supports". Try clicking on the website's "Documentation" tab- I think they got the pages mixed up, that looks like a FAQ. Edited July 22, 2011 by new2net Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted July 22, 2011 Moderators Share Posted July 22, 2011 new2net,Searching (the Search box is at top right ) for AutoItObject will bring up this thread as the top hit.Please do not ask me to explain it - it is way above my level - but those that do say it works well. Have fun! M23  Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area  Link to comment Share on other sites More sharing options...
AdmiralAlkex Posted July 22, 2011 Share Posted July 22, 2011 I can not find any documentation for that code/package. Please adviseDocumentation as in "How to use this, what this supports". Try clicking on the website's "Documentation" tab- I think they got the pages mixed up, that looks like a FAQ.There's a .chm in the download, and lots of examples there and in the thread.Sorry about not putting in a link, I usually do that but it slipped. .Some of my scripts: ShiftER, Codec-Control, Resolution switcher for HTC ShiftSome of my UDFs: SDL UDF, SetDefaultDllDirectories, Converting GDI+ Bitmap/Image to SDL Surface Link to comment Share on other sites More sharing options...
twitchyliquid64 Posted July 23, 2011 Share Posted July 23, 2011 (edited) As stated previously, there is NO support of anything but functions. The autoit parsing model is a simple one. There are, however, some preprocessors and UDFs that will add that functionality. My favorite is au++ Edited July 23, 2011 by hyperzap ongoing projects:-firestorm: Largescale P2P Social NetworkCompleted Autoit Programs/Scripts: Variable Pickler | Networked Streaming Audio (in pure autoIT) | firenet p2p web messenger | Proxy Checker | Dynamic Execute() Code Generator | P2P UDF | Graph Theory Proof of Concept - Breadth First search Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now