Michael Eaton started it, and it sounds interesting, so I'll jump on the bandwagon, too. I need to post something, and maybe this will be a good writing exersize to get the posts flowing again. So, in 500 words (exactly, not counting the bold questions), how I took a flying leap into software development. And feel free to post your own answers, too. How old were you when you started programming?When I was 13 (1992) on the family's first computer: a shiny new 486DX2-66, with 8MB
of RAM, and those big-honkin' VLB I/O and Video cards. How did you get started in programming?Before that computer, I had never used one before, other than typing class in school or playing
MathBlaster or Oregon Trail in the library. I destroyed that machine a quite few times by running every .com or .exe on the machine just to see what it did. (FDisk is a very bad application for the uninitiated to play with.) Knowing how the thing worked led to manipulating it for my own motives: a full set of startup configurations in config.sys/autoexec.bat to eek out every last Kb of base memory. Anything to make Wolfenstein or Doom run just a little faster. And the obsession with video games led me to start writing my own when VB3 launched in '93. Woo-hoo, I could write games!! And I could trash that computer even faster. My mother bought a Iomega Ditto drive to back up her files every night, so that when I trashed it she wouldn't loose anything. I started playing around with web programming in mid-94 with my AOL account, and completely bailed in Windows programming in favor of Web in 1995 when I signed up for one of the first accounts on GeoCities. What was your first language?
Batch Language. Or Visual Basic. What was the first real program you wrote?
A vertical scrolling shoot 'em up in VB3, similar to Raptor (I loved that game) or Tiger-Heli. Even made my own sprites and bitmaps in Paint!! What languages have you used since you started programming?Classroom-only: C++, Perl, PL/SQL, Scheme, and QBasic. Personally/Professionally: ActionScript (Flash), ASP, C, C#, CSS, HTML, Java, JavaScript, Lingo (Macromedia Director), PHP, Ruby, T-SQL, VB, VB.Net, VBScript, and XML. What was your first professional programming gig?
The first code-for-food was in 1995; I got about US$150 for building a few web pages Baypoint Communications. The first full-time gig was in 1999 at Navistream in Rochester, NY (Now BrandLogic) as a New Media Developer. My college's career center didn't have any positions for Web Development, and I was having a tough time finding an internship. I weaseled my way onto the Career Center web site for RIT (near my home town) and found a posting for Navistream. I contacted the company directly and landed an interview. When the interviewer asked me how I found out about them, I told them the story. They were impressed with my initiative and I got the job. If you knew then what you know now, would you have started programming?Yes. Absolutely. It is a little difficult at times, but it is definitely something I love doing. Unless I could have been a professional racecar driver. If there is one thing you learned along the way that you would tell new developers, what would it be?Do it for You, not for Them. In this business, it is essential that you keep the passion and spirit that made you like programming in the first place, otherwise it becomes a chore. Find a company that will encourage that passion, and stay connected with other like-minded people through things like user groups, conferences, or even Twitter. What's the most fun you've ever had...programming?
I particularly enjoy projects that are off the reservation. Amazing things happen when developers get some down-time to go code whatever they want.
Use the site to: - Register for the event
- View sessions details and the event agenda
- Find out who will be speaking at LDODN08 or to get information about speaking there.
- Learn about event sponsors or to learn how to sponsor the event.
- Get a blog badge to place on your own site and let the world know that you'll be there!
Go there now! Check it out!
The first ever Lansing Day of .Net will be held on Saturday, June 21, 2008, at the Lansing Community College West Campus, in Lansing, MI. The event, hosted by Greater Lansing Users Group for .Net, is a one day by-developers-for-developers conference regarding topics related to .Net development, and best of all, it is free. Registration is not yet open, but will be soon. Keep an eye out on glugnet.org and dodn.org for more information.
"We have a great facility and a big chunk of time, we just need to fill the slots with all the brilliant speakers in the area. So if you are willing to come and share your expertise with your fellow developers in the area, please lend a hand." ~ Jeff McWherter
LDODN is currenly looking for interested speakers. If you are interested, please email "program (dot) director (at) glugnet (dot) org" by Wednesday, May 14. Submissions will be selected by Monday, 19 May, and will receive email confirmation.
Scott Hanselman posted an entry yesterday about
Managing Multiple Configuration File Environments with Pre-build Events.
His design uses pre-build events in Visual Studio to copy specific
configuration files to the default file name, such as having “web.config.debug”
and a “web.config.release” configuration files and the pre-build copying the
appropriate file to “web.config” based on which build configuration you are in.
This is a great idea, but large web.config files can get tedious to maintain,
and there is a lot of repeated code. Even using include files as Scott suggests
would help, but major blocks, such as Application Settings, may have to be
repeated even though only the values change. This exposes human error, since an
app setting may be forgotten or misspelled in one of your web.config versions.
At Latitude, we manage this problem through NAnt. One of our former developers,
Erik Nelsestuen–brilliant guy–authored the original version of what we call
“ConfigMerge”. Essentially, our projects have no web.config under source
control. Instead, we have a web.format.config. The format config is nearly
identical to the web.config, except all of the application settings and
connection strings have been replaced with NAnt property strings. Rather than
have a seperate web.config for each environment and build configuration, we
simply have NAnt property files. Our build events (as well as our automated
build scripts) pass the location of the format file and the location of the
property file and the output is a valid web.config, with the NAnt property
strings replaced with their values from the environment property file.
It’s simple. It only takes one NAnt COPY command.
default.build
<project default=”configMerge”>
<property name=”destinationfile”
value=”web.config” overwrite=”false” />
<property name=”propertyfile”
value=”invalid.file” overwrite=”false” />
<property name=”sourcefile”
value=”web.format.config” overwrite=”false” />
<include buildfile=”${propertyfile}”
failonerror=”false”
unless=”${string::contains(propertyfile,
‘invalid.file’)}” />
<target name=”configMerge”>
<copy file=”${sourcefile}”
tofile=”${destinationfile}”
overwrite=”true”>
<filterchain>
<expandproperties />
</filterchain>
</copy>
</target>
</project>
For an example, lets start with a partial web.config, just so you get the idea.
I’ve stripped out most of the goo from a basic web.config, and am left with
this:
web.confg
<configuration>
<system.web>
<compilation
defaultLanguage=”c#”
debug=”true”
/>
<customErrors
mode=”RemoteOnly”
/>
</system.web>
</configuration>
In a debug environment, we may want to enable debugging and turn off custom
errors, but in release mode disable debugging and turn on RemoteOnly custom
errors. The first thing we will need to do is create a format file, and then
convert the values that we want to make dynamic into NAnt property strings.
web.format.config
<configuration>
<system.web>
<compilation
defaultLanguage=”c#”
debug=”${debugValue}”
/>
<customErrors
mode=”${customErrorsValue}”
/>
</system.web>
</configuration>
Next, we need to make NAnt property files, and add in values for each NAnt
property that we’ve created. These property files will include the values to be
injected into the web.config output. For the sake of simplicity, I always give
my property files a ‘.property’ file extension, but nant will accept any file
name; you can use ‘.foo’ if you like.
debugBuild.property
<project>
<property name=”debugValue” value=”true” />
<property name=”configMergeValue” value=”Off” />
</project>
releaseBuild.property
<project>
<property name=”debugValue” value=”false” />
<property name=”configMergeValue” value=”RemoteOnly” />
</project>
Finally, we just execute the NAnt script, passing in the appropriate source,
destination and property file locations to produce our environment-specific
web.config.
nant ConfigMerge -D:sourcefile=web.format.config
-D:propertyfile=debugBuild.property -D:destinationfile=web.config
web.config output
<configuration>
<system.web>
<compilation
defaultLanguage=”c#”
debug=”true”
/>
<customErrors
mode=”Off”
/>
</system.web>
</configuration>
And that’s all there is to it. This is extendable further using the powers of
NAnt. Using NAnt includes, you can put all of your base or default values in
one property file that’s referenced in your debugBuild.property or
releaseBuild.property, further minimizing code. You can use Scott’s pre-build
event idea to have each build configuration have its own NAnt command to make
mode-specific configuration files.
Feel free to use the above NAnt script however you like; but, as always YMMV.
Use it at your own risk.
Enjoy.
I need to just make time to blog. I’m finding that I am getting behind, further and further, as the bleeding edge of technology pulls out ahead of me. [sarcasm]Keeping up to date is hard.[/sarcasm].
I am working on a few things to try to get myself back up to speed, beyond just the on-going procrastination over Microsoft .Net 2.0 certification. Last month, I attended Jay Wren’s talk on IoC with Castle at the Ann Arbor .Net Developers Group. Though we’ve been using Castle within our LMS for a few months now, patterns is definitely one of my weak points in developer-land, so I did pick up a few concepts on Dependency Injection. It was a great talk, and I got some swag!
Last week it was back to AADND for Michael Wood’s talk on Windows Workflow Foundation. I haven’t had much any exposure to Windows Workflow Foundation other than to not call it WWF. This stuff blows me away, and makes me even more jealous that we haven’t converted the LMS out of .Net 1.1. I wish I could have made it to the GANG meeting tonight on WF, just to learn more.
Tomorrow is another meeting, and another “Geek Fest” as my wife so lovingly refers to it as. Heading west to MSU for GLUG’s meeting on C# 3.0 by Bill Wagner. There’s going to be a bit on Code Rush, too (I love CodeRush!). Maybe I’ll win more swag!
CruiseControl.Net 1.3 was released
this morning. To me, most important was the new Build Queue functionality, stopping multiple projects from building at the same time. If ProjectB depends on ProjectA, and they both get code changes committed at the same time, they will fail from contention. Either ProjectA will fail because it can’t delete its old assemblies (because ProjectB has a lock on them) or ProjectB will fail because it can’t find the ProjectA assemblies (because ProjectA deleted them in its rebuild).
No more.
I’m so excited that I am already upgrading our servers!
All right. As mentioned before, here it is: I found a bug in mx.managers.DepthManager in Flash 8, though I’m sure it affects all ActionScript 2.0 versions of the DepthManager to date. The bug involves a lack of error handling when DepthManager encounters an object without a depth, or rather, without a getDepth() method. It shows up through any use of the DepthManager’s methods, the PopUpManager (mx.managers.PopUpManager), the Alert class (mx.controls.Alert), etc., when an object on the stage does not have a getDepth function.
What Happens?
The issue manifests itself in many variations, usually by objects placed with the DepthManager inexplicably replacing previous objects placed with the DepthManager. Most notably, it manifests itself as modal windows (via PopUpManager) and Alerts not rendering to the screen, even though the modality seems to have worked and all other objects on the screen no longer can receive input.
Why does this happen?
The DepthManager works off a rather inefficient array to maintain its records. An object within the DepthManager, the DepthTable, is an indexed array containing record of every object on the stage and its depth. The DepthManager stores a reference to the object within the array at the position corresponding to the depth of the object. If the stage has one object at a depth of 32,000, depthTable[32000] = myObject, and we have a 32,000-length array with one object stored in it [an inefficiency]. Values in the manager’s depth table are based on available positions in the array, such as kTopmost being greater than the last movieclip or object in the array [it iterates one-by-one through each position in our 32000-length array; another inefficiency].
Excerpt from mx.managers.DepthManager.as var t:String = typeof(i); if (t == “movieclip” || (t == “object” && i.__getTextFormat != undefined)) if (i._parent == this) { depthTable[i.getDepth()] = i; }
However, the DepthManager code is assuming that the object has a getDepth function. If the object does not have the function, references to that function return undefined, setting depthTable[undefined] = i, which blows chunks all over the place, and any reference to any of DepthManager’s depth-returning methods will always return zero.
That zero is why nothing works anymore; the Alert class creates the new Window-class-like object, then creates a transparent movieclip below that object to trap all inputs, creating a sense of modality. The Alert class uses the DepthManager to create itself at kTopmost, which DepthManager says is zero. The Alert class then uses the DepthManager to create the modality movieclip above itself, kTopmost, which it then hopes to swapDepth with to get itself back above the modality clip. However, the Alert class, with itself at depth zero, creates the modality clip at depth zero because DepthManager said it was the kTopmost depth. Creating an object at depth zero toasts any object already at depth zero, thus the modality clip blows away the Alert clip and we get a SWF that no longer responds to anything, and no Alert ‘OK’ button to restore peace in the world. Likewise happens when a modal window is created through the PopUpManager.
So what can I do about it?
How do you get around this? Simple. Don’t put anything on the stage that extends from Object. If you put it on the stage, extend it from MovieClip. Even though the DepthManager code (above) explicitly calls getDepth on MovieClip or Object, it does not check to see if the object in question actually has a getDepth method. Object does not have getDepth by default, but MovieClip does. I suppose you could write your own getDepth function for your Object-inheriting class, or you could rewrite the DepthManager (which would mean also rewriting PopUpManager, Alert, ComboBox, and a
half-dozen other controls), but it is much simpler to extend from MovieClip.
Why it happened to me
I have a movie that is 170KB. There’s a lot of crazy mojo in there, and I want my prel0ader to load within the first 1KB, not after 170KB. So, I created my preloader, removed “Export in First Frame” from everything, and set my classes to export in frame 5 (after the end of my preloader loop). However, this made a few of my Object-extending components no longer work anymore since they were not referenced in the “Assets” layer of any of the other components (no reference=no load, much like the DataBindingClasses), to I had to drag them to the stage to ensure that they loaded.
*Poof*
My world exploded.
I lost two days of work tracking this little punk down. And you already know the rest of the story.
|