The Blog
Apr 29, 2008
Switching to Entourage from OS X Mail
I recently switched from OS X Mail and iCal to using Entourage in Microsoft Office 2008. It has been a bit of an odd transition; iCal and Mail really came of age with Leopard, and moving from them to a Microsoft product has been tough.
Of all the Office 2008 apps, Entourage feels the least polished. Moving around the app causes things to happen that I wouldn't expect (hard to define anything specific, it just isn't as intuitive as iCal and Mail), the UI is often cluttered, and stupid things like not being able to save the location for the preview pane as part of a saved search really annoy me. It's not horrible, but it's certainly less than Mac-like in many ways.
It's not all bad. Importing items from iCal, Address Book, and Mail was very easy and mostly intuitive. Much of the placement of favorites and commonly used items is flexible and intuitive. I am getting used to the way that Entourage manages to dos, and things like keyboard shortcuts for saying "do this task some time next week" (after which it sets the start and end dates for you) or "make this mail message a to do" (after which it shows up in my itinerary as a hybrid email/to do item) are very useful. I miss iCal's integrated windows and workflow, though; Entourage uses a lot of modal dialogs, which always bothers me - especially after years of using OS X, an OS that never uses a modal dialog unless it absolutely has to.
Some other things Entourage does well include the reminder system. I love being able to "snooze" an event. I often set reminders well ahead of time so that I have a chance to reach a reasonable stopping point on my code before mentally changing lanes to handle a meeting or a phone call, but I often dismiss a notification and then find myself late for my next commitment. Entourage lets you "snooze" an event, after which it reminds you again - very cool.
One final item I have heard about from other people at work is that our Kerio server (basically a cheaper, reverse-engineered implementation of groupware emulating an Exchange server) doesn't play completely well with Outlook on Windows. However, I was able to hook up to the Kerio server no problem with Entourage, so that was a nice addition.
All that being said, having Exchange server support and being able to put things in my desktop calendar/address book/email and get them on my company-issued Blackjack within seconds is pretty darn cool. Cool enough to suffer Entourage in its current state, at least. I think Entourage has potential, but Microsoft's Mac BU really needs to work on the UI and workflows.
Something I discovered today has certainly made me enjoy Entourage a little more. By default, Entourage uses Microsoft Office shortcuts, which means that you have to use the Home and End keys to do certain things (like selecting a line of text). I was retraining myself to use these non-Mac-standard shortcuts, but it was totally annoying me. I've discovered that under the "General" tab, there is a checkbox for "Use MIcrosoft Office keyboard shortcuts for editing text." Turning it off has returned me to my usual keyboard mappings, which makes me a much happier bunny.
Apr 27, 2008
Just When You Thought Ethanol was a Lost Cause
A company has discovered how to make ethanol from just about any waste product (via Digg). Looks like they are putting together a demonstration production facility; they basically want to make money by franchising their bio-organisms and processes, so this makes sense.
I had heard a lot of arguments against ethanol in the past, but this company's offerings might settle them.
MacBook Pro Batteries
I bought my current MacBook Pro laptop back in May 2006. The computer has been (and continues to be) a thin slice of aluminum "teh awesomeness" that makes all computer-related activities a pleasure.
There has, however, been one exception to this state of portable computing nirvana: the longevity of the battery. Within the first year after I bought my MBP, the battery life dropped to the point where a full charge would only give me an hour or so of usable time regardless of power settings. Note that I do like to wander around a lot with my computer when I'm at work and at home, so I expect my batteries to die pretty fast - but under a year of use is simply unacceptable.
Apple gets a lot of crap for certain issues with their products, especially with first-run hardware revisions like my MBP, and has often been outright stubborn in resolving them. However, when it came to the battery issues I've had, they have been wonderful.
With my first battery issue, I wandered in to an appointment at the Genius Bar and left with a shiny new battery - no questions asked. I was still under warranty, after all. But when my new battery started to give me a mere hour of use in the last month or so, I expected I was going to need to buy a new one out of pocket since my warranty has expired.
Turns out that this isn't the case. Not only did Apple replace my first battery while under warranty, but after the battery issues that original MBP owners had, they implemented a program where you can get coverage for up to two years on your battery, regardless of whether or not you bought AppleCare. So, once again, I wandered up to the Genius Bar today and left with another shiny new battery (2:40 of usable time left as I write this post).
If you have an original MBP and are concerned about the battery, please check out the
written information on Apple's site concerning the replacement program.
You can tell you have a bad battery by following these instructions:
1) Go to the Apple menu and select "About This Mac".
2) Click on the "More Info..." button in the dialog that pops up.
3) System Profiler opens. Go to Hardware > Power in the left hand side bar.
4) Under "Battery Information", check the "Cycle Count" and the "Full Charge Capacity". Apple guarantees batteries for 300 cycles (a cycle is a full charge and discharge).
If your cycle count is less than 300 but your battery life is poor, then you should go in for a replacement. After 254 cycles, my battery only showed a "Full Charge Capacity" of around 2500 when I took it in, whereas my new battery shows a full capacity of 5569.
I'd recommend taking in a print out of the replacement program page with you to smooth over the Genius Bar visit. Good luck, and let me know your experiences.
Apr 22, 2008
dpuint - Unit Testing for Flex 2 and 3
Since we were in need of a unit testing suite for Flex apps at
Highwinds, I started looking in to FlexUnit and some of the other options.
While I was doing this,
Tommy suggested I check out
dpuint. No, that's not a typo - it's called dpuint to stand for "digital primates Unit and Integration".
Turns out it's pretty cool. I never got to mess with FlexUnit much, but based upon the documentation there seems to be numerous improvements in dpuint over FlexUnit. I got some tests up and running today with testing asynchronous processing and they all worked like a treat. The test runner for dpuint also showed me the execution time for each test, which was nice to have available (I don't think this is a distinguishing feature for the library - I just wanted to bring it up).
One of the things that was really refreshing to see was
a great tutorial for the framework on the Google Code site. If you have used any of the xUnit testing frameworks before, you will feel right at home; the only thing you will need to learn is how to wire up asynchronous tests, which doesn't take long. FYI, I would recommend looking at the
Cairngorm example (look for "Testing Delegates") since the
basic timer example they offer earlier in the tutorial only really shows you how to test an asynchronous call that fires an event. This is certainly a useful feature and worth knowing about, but not appropriate for testing service-level classes like gateways to services (which is what I was doing).
As a quick sample, here's a few methods from the beginnings of a test suite I wrote to wrap my head around the framework. This is intended to be a quick reference to the framework rather than an example of great unit testing practices, so please keep that in mind.
public class RawDataPointManagerTest extends TestCase
{
private var fixture : RawDataPointManager;
override protected function setUp() : void
{
fixture = new RawDataPointManager();
}
public function testFetch() : void
{
var passThroughData : Object = null;
var responder:IResponder =
asyncResponder(new TestResponder(handleFetchComplete, handleTimeout),
3000,
passThroughData);
fixture.fetch(new DataSetCriteria(), responder);
}
private function handleFetchComplete(event : ResultEvent, passThroughData : Object) : void
{
var resultArray : Array = event.result as Array;
assertEquals(45000, resultArray.length);
}
private function handleTimeout(info : Object, passThroughData : Object) : void
{
fail(FaultEvent(info).message.toString());
}
}
To explain,
RawDataPointManager.fetch() accepts a
DataSetCriteria object, which calls a web service behind the scenes, returning asynchronously as all service calls do in Flex.
fetch() also accepts an IResponder so that it can be used by multiple clients that might process the result events using different responder functions for success and failure.
The
asyncResponder call invokes a method in the TestCase class from which my suite extends. This produces an IResponder reference that will wait 3000 milliseconds (a wait value that is specified in the method call) before assuming that the call failed. If the call fails, the
handleTimeout method will be invoked (it's being passed in by reference through the
TestResponder); on success,
handleFetchComplete is called instead.
In either instance, you can pass along "pass through data" with each asynchronous call. This is usually data you will use to assert equality, a boolean value, or whatever else your test is looking for. This info gets passed along to the success and fault handlers so that they can maintain state easily. In my example I am passing null - I just wanted to leave a reminder in there for me to look at tomorrow when I start writing less contrived tests. This pass through data is especially useful when you want to (for example) set a text field to a value and make sure that the value stuck. There's a good example of a use case for this in
the tutorial for testing UIComponent. Obviously, you'd probably be testing more useful functionality than validating a text field's input was set, but you get the point.
In my assertion, I know that I have a sandboxed test data set that always returns 45,000 members in an array. Using this sandboxed data I can write very specific tests to make sure that the data is being retrieved and processed as expected. In
handleFetchComplete(), I am currently just validating that the expected number of data rows is being processed and returned to the caller.
Hopefully this will give you enough info to see how easy it is to use the dpuint framework for testing asynchronous method calls. Please check out their web site for more info and let me know your experiences.
Join the Max Fleet at Highwinds
Tommy introduced me today to wordsmith.com and the anagram generator. Turns out that one of the anagrams for "Flex Team" is "
Max Fleet." Kind of funny considering I'm the Flex Team Lead over at
Highwinds now.
So, come on over and join the Max Fleet/Flex Team - I've got two openings at present here at the Winter Park, FL office (local candidates only, please). Here's the job description (exported from Word to plain text with a little HTML for formatting - YMMV). If you are interested in applying, please send your resume over to careers [ at ] highwinds.com with the title "Software Engineer - User Experience Team."
Software Engineer - User Experience TeamHighwinds is a growing provider of software, messaging and distribution services. Our products are sold to the worlds largest ISPs. We are actively seeking ambitious, dynamic, smart and energetic individuals to be a member of the team that designs, operates and improves our growing content distribution network.
If you are motivated to deliver high quality and innovative services, Highwinds can offer you a great career opportunity. We offer benefits including 401k, medical, dental, vision and competitive salaries to qualified team members.
About the User Experience TeamWe're a fast-paced, growing software team creating a cutting-edge user experience product on top of a next-generation Content Delivery Network (CDN).
Every member of our team is focused on the needs of our customers and the future of our business, and your work will directly impact how the company and product get to the next level. When you join our team, your ideas will shape the future roadmap of the platform as you bring them to life through code.
Required Personality If the following description sounds like you, you are going to love being a part of our team.
You have strong passion for high-quality software and the ability to deliver product in an informal, agile environment.You prefer a whiteboard brainstorming session to written specifications.You don't need a manager. Once you have some direction, you take responsibility for the work at hand and have the initiative, imagination, and motivation to get it done.You like to learn from others, and to share knowledge and best practices. You're a fan of collaborative design and peer reviews.You have excellent deductive reasoning, problem solving, and decision-making skills. When it's necessary to compromise to meet a deadline, you're confident you can make the right decisions to achieve a balanced result.You have a positive attitude with excellent interpersonal/communication skills. You're happy working both independently and with others in a multi-team setting.You're not comfortable unless you're at the top of your game. When you're not at work, you're tinkering with new technologies or catching up on ideas from industry thought leaders. You might even have your own blog.You're interested in working with Rich Internet Application (RIA) technologies.Job RequirementsThese are the bare minimum skills expected for members of our team.
Bachelor's degree in a software-related field (Comp. Sci. or equivalent strongly desired) or comparable industry experience, plus 4 or more years of professional experience as a software engineer in a team environment of any size.Demonstrable expert-level understanding of object-oriented technology and industry design patterns. Professional experience delivering applications in Java/JEE or C#/.NET.Strong written and verbal communication skills, including the ability to present ideas in a group setting and constructively critique the work of others. Experience with an RDBMS platform such as Oracle, MySQL, MS SQL Server, etc.Experience working with source control systems in a parallel development environment (Subversion preferred).Understanding of software development lifecycles and associated development techniques.Development experience using a server-side web development platform (any of the following or their equivalents: ASP, ASP.NET, JSP, ADF, ColdFusion, Ruby on Rails, Java servlets, JSF, PHP, etc.).Thorough understanding of the strengths and compromises of distributed application design using web services, REST architecture, and/or other remoting technologies.Experience with software development in both Unix/Linux and Windows environments.Desired QualificationsThe best candidates will also possess one or more of the following.
Strongly desired: professional or hobby experience with Rich Internet Application development using Adobe Flex 2 (or higher) and ActionScript 3.Proficient with the web technology stack (one or more of the following: JavaScript, HTML, XHTML, CSS, Ajax). Experience developing web applications for multiple browsers and operating system platforms.An eye for clean user interface design and a passion for delivering a high-end user experience.Working knowledge of graphic design tools (Adobe Creative Suite, Gimp, PixelMator, etc.) a plus.Familiarity with UML modeling.Experience with the setup and administration of web server platforms (Tomcat, JBoss, Apache, etc.).Socket-based programming experience a plus.Experience working with geographic/marketing data.
Apr 18, 2008
Flash/Flex Events: Error Removing Child with Custom Event
So, I discovered yesterday that if you create a custom event with an event type name of "remove" that happens to also be associated with a call to removeChild() in any of your components, you will end up with the following error (some class names removed to avoid disclosure issues):
TypeError: Error #1034: Type Coercion failed: cannot convert mx.events::FlexEvent@17977d31 to [your custom event name]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.core::UIComponent/dispatchEvent()[E:\dev\3.0.x\frameworks\projects\framework\src\mx\core\UIComponent.as:9051]
at mx.core::Container/http://www.adobe.com/2006/flex/mx/internal::removingChild()[E:\dev\3.0.x\frameworks\projects\framework\src\mx\core\Container.as:3307]
at mx.core::Container/removeChild()[E:\dev\3.0.x\frameworks\projects\framework\src\mx\core\Container.as:2261]
at [code invoking the removeChild() event]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.core::UIComponent/dispatchEvent()[E:\dev\3.0.x\frameworks\projects\framework\src\mx\core\UIComponent.as:9051]
at [code broadcasting the custom event]
at [component broadcasting the call to create the custom event]
Obviously, there is something in UIComponent on line 9051 (yikes! that class is stupid huge) that is causing an issue. I went in and looked at the code via the debugger, and the underlying issue is compiled in to a SWC that I couldn't see. I guessed that the name of the custom event was too generic, so I changed it to something that wasn't "remove", and the issue went away.
Talk about leaky abstractions. :)
Apr 5, 2008
Why Wikis at Work are Wonderful
We created a Wiki at CFI some time back and have been seriously filling it with content for the last twelve months. People often mistakenly give me credit for the idea, but it was Jeff Marder's call over three year's back when he worked for me on the web team. We're already reaping the benefits.
I've recently gotten access to the Wiki at Highwinds, which is far more mature than the one we have at CFI, but it gives me a great sense of where CFI's one will go and how much they will rely on it in the future. I'm basically getting a first pass at my new company's orientation and training, for free, over the Internet, on a weekend. If you don't have a Wiki at your job regardless of your field, talk to the right sys admin and get one right now.
And as for you lot at CFI: WHY ARE YOU WASTING TIME READING MY BLOG? GET BACK TO WRITING WIKI ARTICLES! :)
Farewell CFI, Hello Highwinds
Friday was the first day I was able to let everybody know that I am leaving my position of Director of Software Architecture at
CFI/Westgate Resorts to join
Highwinds as their Flex Team Lead. I'll be reporting to Highwinds CTO Josh Gagliardi, and my team will be working on building out
StrikeTracker to its full potential (FYI, the quality of the web site and marketing materials don't do justice to either the company or their products, as I found out when I interviewed with them). My last day at CFI will be Thursday April 10th, and I'll be starting at Highwinds on Monday April 14th.
I stumbled across this opportunity while considering moving out to the west coast to work for a tech firm. I've had great fun these last seven years in corporate IT, but I miss coding awfully, and just don't have enough time to slake my codelust on projects at home. Additionally, my personality and interests have felt increasingly mismatched in the corporate environment the longer I have stayed there: it just takes too darn long to get everybody to agree to go in the same direction, and the politics does nothing but hamper the ability of a technical team to work fast and be creative. I understand that this is a necessary evil for certain larger companies, but at the moment I'm dying to get in to a small shop where I can work rapidly with brilliant people on cutting edge products, wear jeans to work, and use a Mac without others looking at me like I'm "one of those people." (The fact that Highwinds is also on AT&T and I can get an iPhone is just icing on the cake :) ).
I'm not fully on board at Highwinds yet, so I'm not sure how much or how little I'll be able to blog about - but I do know that I will be able to blog. Working for a company that relies on its software as its revenue stream obviously raises concerns with regard to distribution of intellectual property, and as a result I'll need to run anything work-related by the boss before I talk about it here. I'll do my best for all three of my readers, since I enjoy blogging about what I'm doing when I can, and a lot of the stuff I will be working on will be right on the leading edge of where RIA development is going.
CFI has been wonderful to me in many ways. They had no issues promoting me through the ranks regardless of my youth, gave me the autonomy to do great things during my tenure, and suffered my often rebellious and stubborn antics because they knew I had their best intentions at heart. The experience I gained there is launching me in to the next phase of my career, and I can't thank everybody at the company enough. I have been both greatly humbled and flattered by the things people on my team have told me my contributions have done for them personally and for the company as a whole; it makes me glad that the good mojo has flowed in both directions.
With my departure, CFI is looking for a new technology visionary, and I have two open Flex/AIR developer positions on my new team at Highwinds. If you are interested in either job, please contact the
HR department at CFI (for the visionary position) or me at maxim[dot]porges[at]highwinds.com for the Flex/AIR spots. I'll be posting more info about Highwinds and the opportunities there as I get on board next week, so watch this space.
CFI was my first career experience, so leaving there was also a first for me. For anybody leaving and/or joining a company (which usually happen around the same time), here are two articles I found really useful in getting my head around what to expect (at the very least, the resignation checklist has served me very well so far!).
For the leavers: Your Resignation/Layoff ChecklistFor the joiners: Your First 90 Days
Apr 1, 2008
Hear Me Ramble on the CFWeekly Podcast on Flex Frameworks
I was fortunate enough to be invited in to a very interesting podcast (well, interesting if you're a Flex developer) over on CFWeekly. Rather than repeat myself, I'll just
send you over to the Adogo blog.
By the way, LeGros did an excellent job this evening in presenting two detailed topics in a limited amount of time. Be sure to
check them out (look for the April 1st, 2008 meeting resources).