It’s about that time I learn Ruby

In an effort to better recall stuff as I’m learning Ruby, I will be using my WP install for note-taking since no one visits this site ever (based on usage stats).

Ruby Basics

It’s multi-paradigm and interpreted. This means that Ruby is able to behave as a functional, object-oriented, and imperative language. As an aside, it seems like it would be confusing if you haphazardly combined all 3 styles in a single application, you should attempt to eliminate inconsistency and stick primarily with a single pradigm?

Functions

  • puts(): prints a string. Returns nil
  • gets(): gets a line of input from stdin, including \n, returns it.

Strings

‘Single-quoted’ or “Double-Quoted”. Single-quoted are limited to 2 escape sequences, \’ and \\. Double quoted can use the entire set of escape sequences. There is apparently a slight performance benefit to using single-quoted strings if you don’t need escape sequences.

Sequences I have never seen before in other languages…

  • \c? and \C-?: CTRL+?
  • \M-?: META+?
  • \C-?\M-?: CTRL+META+?
  • \e: ESC
  • #{…} : Returns value of Ruby Expression inside {…}. Like back-ticks in Bash I guess.

Other ways to declare strings…

%q{str} or %Q{str} or %q;str; or %Q;str; all function as single and double quoted strings, respectively, returning ‘str’ or “str”.

variable = <<END
..
..
END : is known as “heredoc” format. This exists in bash and PHP so it’s nothing new.

to_s() : to_s() is the toString() method of Ruby.

Numbers

Fixnum and Bignum are the 2 number classes. -2^30 to 2^30-1 gets converted to Fixnum. Anything else is Bignum.

  • 0x#### = Hex
  • 0#### = Octal
  • ##_## = #### (underscores are ignored)

There are also Floats that work as expected, but you can use exponential notation

  • 1.2338
  • 42.42e5
Lastly, the numbers are objects so they have methods like:
  • ##.zero? = true/false
  • ##.abs = abs(##)
All the arithmetic operators you expect are there +,-,*,/,%,()

 Collections/Containers

You can create a collection by defining a range using .. or

  • col = 1..9
  • col = 20…25

Trip-dots … will not include the last value in the collection. Double-dots .. will. The == operator is used to check for equality. Alternatively the .eql?() method can be used for this same purpose. === can be used to check for existance of an element in a collection. Alternatively, .include?() method does the same thing.

Arrays

Arrays in ruby work like they do in other languages, but there is no type restriction nor do you declare the type the array holds.

  • empty_array = []
  • also_empty = Array.new
  • set_array = [ 'one', 'two', 'three' ]
  • mixed = [ 'string', 10 ]

You can also create arrays from strings:

  • %W( here are some words ) = ["here","are","some","words"]
  • %w( some more ) = ["some","more"]

Note that capital W will process the string as if it’s double quoted, applying escape sequences as needed. On the other hand %w will use the literal interpretation of the string as with single quotes.

Objects also typically have a .to_a method, that converts the object’s contents to an array. This can be used on collections to get the array version of the collection.

>> col.to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9]

Note that not all objects implement this method. You can add elements to an array by referencing a non-existant index in the array. Any un-defined indexes between the added item and the last item in the pre-appended array will be set to nil or ruby’s version of null.

>> arr = col.to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9]
>> arr[0]
=> 1
>> arr[10] = 'cheese'
=> "cheese"
>> arr
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, nil, "cheese"]

In addition, there are the .push() and .insert() methods. .push() takes a comma separated list of items to push on the end of the array. Insert takes an index and an item to insert at a specific point in the array. The index can be negative, in which case it is referring to counting backwards from the end of the array and inserting there.

There is also the << operator which pushes items on the end of an array. This can be chained to add multiple items.

Indexing

You can index an array like you’d expect, using [] operator. The cool thing about ruby is you can pass a collection of indexes and ruby will return the subset of indexes from the array that matches that range collection. ie. arr[2..5], or even the variable name of a collection. Crazy. If you send a collection that isn’t a range, you will get a TypeError.

.at(i) can also return an item at a specific index. .fetch(i, default) does the same thing, but lets you specify a default value to return when trying “fetch” an item. .values_at(list,of,array,indexes,default) does both what at and fetch can do, except it can take a list of indexes you want back.

.pop  and .shift are methods which do as expected, .pop pops the last item from the array, and .shift shifts the first element off the array.

.delete_at(i) deletes the item at the index, and returns it. .delete(i) { default } also behaves like .delete_at, but you can specify a default value to return if the item in question doesn’t exist.

The Hash

A hash table. You can use objects to index items in the hash. Objects must implement .eql? method and must have a hash code to be used as keys.

  • hash = { “something” => “else”, “another” => “thing” }
  • hash = {}
  • hash = Hash.new
  • hash['something']

Ruby  allows you to put newlines in a hash definition, using commas as delimeters. Hash.new(default) doesn’t set the values of the hash, it instead sets the default return value if a key doesn’t exist in the hash. You can index hashes like arrays. Hashes offer many of the same methods as arrays.

.has_key?(key) will return a boolean if it hash has key, .has_value?(val) will return a boolean if hash has a value. .empty? returns a boolean if hash is empty. .clear clears a hash’s contents.

Interesting PHP “Glitch” on PHP 5.3.13

Recently at work, I came across a very confusing convoluted bug. We had upgraded the PHP version our panel ran on around May to keep up to date. After the upgrade, we got suddenly started getting fatal errros during the install/activation phase that looked like:

PHP Fatal error: Access to undeclared static property: Test::$_instance in /root/test3.php on line 22

This looks kind of bad to have this pop up on your installer but luckily all the actions that needed to be completed by the installer were occurring just fine. What made this hard to figure out, though, was that this error was coming up only in this one case. In order to figure out what was going wrong, I had to dig through some dragon code that had become mangled confusing mess after years of tweaks/fixes/feature additions. Ultimately this led us to completely refactor the code in question.

The error was being caused during the destruction sequence of a class we used to handle our master configuration file. Basically we allow the programmer to set values of the configuration in memory without touching the disk. Then, the plan is to write data on the destruction of the class so the programmer doesn’t have to explicitly call the method that writes. The programmer interacts with the class in a static context, but in order to store data there is an internal, private, singleton instantiated object of the class that holds the current configuration read from the file plus any in-memory changes the programmer has asked for. I had never heard of this OOP design pattern singleton, as Pitt doesn’t teach it and frankly, it seems to have fallen out of fashion. To add to the confusion, there really isn’t a way for the programmer to get at the instance. There is no get instance. So basically from outside, the programmer treats the class as a static utility class but inside there’s all this messy construction and destruction occurring on a regular basis. Cool right?

Not cool. Confusing. So let’s walk through this. On script termination, PHP calls your class destructors as it’s cleaning up memory before the script terminates. During the destruction of our class, we want to write the memory-stored changes the programmer may have made to the disk. BUT, here’s the caveat – what if there had been changes to the ini while the process was executing by another process? Our in-memory image of the configuration is dirty, we have to reload the configuration from disk prior to writing. A while ago this actually had become an issue so someone shoe-horned in some logic to make it so that before writing to disk, we dump the current in-memory configuration and reload it. The only problem was that in order to re-load data, you had to re-instantiate the object.

Re-instantiation involves setting the variable that holds the object’s pointer to NULL and then calling new Class(). When PHP sees this though with a singleton class, you have suddenly made it so there are no more references to that object and the destructor is called immediately. Well guess what. The destructor checks to see if there needs to be a write. How does it do that? By checking the instance of the class to see if there are changes that need to be written. What if the varibale that points to the object is null? It uses a private getinstance() method to generate a new one and uses that to check if there are writes that are needed (which with a freshly constructed object, there are none). You can already see the confusion starting to form here, during the destruction of the object, a new object must be created in its place to determine the need for writing.

In most cases, PHP handles this like a boss but in our case, PHP got confused. So basically a write triggers a “reload” which is just unsetting the private static singleton instance variable to NULL, which triggers a destruction. The destruction triggers another write, which (since the variable referencing the instance is now NULL from unsetting it), creates a new instance of the class. The new class does not have any data which needs to be written, so the destruction triggered by the unsetting of the private instance variable does not write and return. The reloading then picks up the instance variable created during the destruction and uses that as the basis for making changes and writing. If you’re like “well the instance variable being re-constructed would mean you’d lose any ini changes you made in memory”, you’d be right except for the fact that we save it locally on the stack in the write() method before we reload. So we have our changes and a new instance of the class, we have the ini file locked before the reload, we easily can use the stored changes in the write() method and the fresh class instance to make an accurate write to disk of the config file contents.

So now that we see that, the actual bug or problem is that PHP gets confused when we call write() explicitly in our code and the above happens, and then write() is implicitly called as the script terminates in the destruction. Since the explicit call of write() guarantees that the destructor is called right then and there, it seems that PHP’s memory management system is then broken for the shutdown sequence. The final shutdown sequence goes like this:

1. __destruct()
 2. write()
  3. reload()
   4. __construct()
   5. pop _construct()
  6. pop reload()
 7. pop write()
8. pop __destruct()
9. __destruct() again for the variable created in reload()
 10. write()
  11. fatal error when you attempt to access the singleton instance.

PHP appears to destroy the wrong object on the final destruction. Here is a stripped down version of what will trigger the bug:

<?php

/**
 * PHP 5.3.13 Bug POC
 * Author: Dan Motles, Paul Oehler
 * <dmotles at interworx dot com> <poehler at interworx dot com>
 */
error_reporting( E_ALL );
ini_set( 'display_errors', 1 );

class Test {

        private static $_instance = null;

        public $reload = false;

        private function __construct() {
                echo "Constructing " . spl_object_hash( $this ) . "\n";
        }

        public static function getInstance() {
                if( is_null( self::$_instance ) ) {
                        self::$_instance = new Test();
                }
                return self::$_instance;
        }

        public static function reloadIfNeeded() {
                if( self::getInstance()->reload ) {
                        self::$_instance = null;
                        self::getInstance();
                }
        }

        public function __destruct() {
                echo " Destructing " . spl_object_hash( $this ) . "\n";
                self::reloadIfNeeded();
        }
}

Test::getInstance()->reload = true;

Test::reloadIfNeeded();

Test::getInstance()->reload = true;

and here is the output:

Constructing 000000004bf6e2fb00000000187cbabb
 Destructing 000000004bf6e2fb00000000187cbabb
Constructing 000000004bf6e2f800000000187cbabb
 Destructing 000000004bf6e2f800000000187cbabb
Constructing 000000004bf6e2fb00000000187cbabb
 Destructing 0000000018b66d120000000018ea290f
PHP Fatal error:  Access to undeclared static property: Test::$_instance in /root/test3.php on line 22

Fatal error: Access to undeclared static property: Test::$_instance in /root/test3.php on line 22

Notice that the hash value of mysteriously changes on the final destruction. If we remove the  2 last lines, the call to reloadIfNeeded and getInstance, the destruction goes off without a hitch!

Constructing 000000000f5c83740000000024b4d0dd
 Destructing 000000000f5c83740000000024b4d0dd
Constructing 000000000f5c83770000000024b4d0dd
 Destructing 000000000f5c83770000000024b4d0dd

So obviously, code is stupid and needs re-factored. It was a good afternoon’s worth of troubleshooting to figure out what was going on.

Making vim into an IDE

After struggling hard-core with eclipse on Windows, I decided I wanted to return to my roots when thinking about a development environment on my new Mac. The problem with vim is that off the bat, it lacks all the nice things I did like about eclipse:

  • FileBrowser
  • Code-Completion
  • Method and class listing
  • Jump-to-definition of class or method
  • Quick-file open

It was a conundrum trying to deal without these features in the gigantic code base that is InterWorx. So, I decided to poke around a bit and see if I could make something reminiscent of and IDE using vim, mostly for morbid curiosity and as a challenge. In addition, all of the vim evangelists praise vim as being highly modular and extensible – so why not.

Function and Class Listing

The first thing I wanted was a list of all the methods and classes within a file right next to my editing window. I simply could not survive by mindlessly scrolling around the file as I had become accustomed to using eclipse’s source explorer thing. Luckily, I had experience with this before and quickly installed Exuberant Ctags and taglist.vim, both of which gave me a list of functions, variables, and constants right next to my editor window which allowed me to hop around my file quickly from one function to the next.

File Browser

In order to see a list of files in my project, I knew I wanted a tree-like file browser. This problem was solved easily by NERDTree, a very powerful file browser plugin.

Code Completion

Code completion seemed tricky at first until I found that vim comes bundled with “Omnicompletion“, a tool that uses your tags files in order to figure out based on partially typed in words what is the most likely tag (i.e. method or class) you are referring to. In order to supplement the omnicompletion feature, I decided to pick up phpcomplete.vim so that the feature would work better with PHP files and I used ctags to generate a recursive tag dictionary of my entire InterWorx project directory.

Jump-to-definition of class or method

This actually was sort-of built into vim already too if you had a tags file generated by ctags. You can use CTRL+] with your cursor on a token to jump to the first most likely tag, g[ to show all tags that match the word your cursor is on, and CTRL+t to go back to where you were before you jumped to a different tag. Pretty nifty.

Quick-file open

CTRL+SHIFT+R in eclipse gives you an open resource window which makes opening files in your project relatively painless. Command-t is the vim plugin that also provided me the same functionality. I am a happy camper.

Conclusion

While the end product is not a full IDE yet, it’s getting there. My hope is with further refinement I can get something that is a very powerful multi-lingual IDE that only I can use :P .

Github project here.

ALL HAIL THE NEW DAN.MOTL.ES

The last site was jokes. Terribad. I have decided to just go with the easy drop and run wordpress install, it will make things easier going forward.

So basically to reiterate what was going on before on my old site, I am Dan. I do CS at University of Pittsburgh, work for a small company called InterWorx. I mainly do software development and technical support there. We are a small company, though, so I get to do a lot of fun and exciting things. For example, the other day the bathroom was dirty, so I cleaned it. Put a check next to janitor. We needed trash pickup and water delivery for our cooler, so I scheduled that. Put a check next to office manager/HR. I interact with some of our integration partners as well as clients – that’s like sales and partner relations. I’ve also dealt with hiring/management with makes me even more HR’ish.

Goals in life:

  • Learn enough math to understand fourier transforms.
  • Work on fun projects with good people.
  • Figure out how to solve the terrible transportation issues in Pittsburgh. Fuck yellow cab. Seriously.
  • Figure out how to stay fit while at the same time going out and drinking every night. Or just get fat and drink every night.

This upcoming semester, it will be rough. I’m currently scheduled 18 credits

  • CS1510 – Algorithm Design
  • CS1566 – Intro to Computer Graphics
  • CS1571 – Intro to Artificial Intelligence
  • CS1622 – Intro to Compiler Design
  • CS1652 – Data Communication & Computer Networks
  • CS1900 – Internship Course Component

I may die. In reality I’m thinking I might be able to handle it because CS1900 will be relatively low-intensity 1-day a week course. On the other hand, Algorithm Design is supposedly one of the hardest undergraduate courses that Pitt offers. I’m tempted to take the challenge, simply to see if I can survive my final semester at Pitt. I may take a GPA hit, but at this point I figure it’s high risk – I might not make it through and may have to take a ‘W’ or worse, I might not drop in time and I might have to take a couple B’s.

I also want to qualify the Computer Graphics decision. I actually don’t want to be a “game designer” anymore – that dream fizzled and died in my early 20′s. In reality, I never took a linear algebra course and I want to understand the process of rendering graphics on screen. I may never use this skill but while I’m at Pitt I’m going to try and bleed as much information out of that school. I think in the real world it’s going to be a lot harder to want to sit down with a text book on a daily basis to learn a new skill.