mirror of
https://github.com/zaphar/jeremy.marzhillstudios.com.git
synced 2025-07-21 19:29:48 -04:00
Import from hg version of the site.
This commit is contained in:
commit
5621dd037e
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
generated*
|
||||||
|
.gost*
|
6
_content/A-beautiful-thing-2005-5-11.yml
Normal file
6
_content/A-beautiful-thing-2005-5-11.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: A beautiful thing
|
||||||
|
time: 2005-05-11 00:26:46
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
One of the beautiful things about web app's is the install. There is none. Nothing. Of course web apps aren't the only thing with that feature. I hear, although have not verified, that OS X's instal process for applicationsl is as simple as copying a folder over. Many open source applications are the same. copy a folder or a binary and your done. No editing the registry. No registering services. <strong>No <em>mess.</em></strong> The uninstall? Just as easy.... delete the folder. Web apps are perhaps a little superior in the uninstall department. Just don't go back to the page. No install means no uninstall either. No registry corruption. No forgotten registry entries hanging around clogging your machine. No services left behind. <strong>No <em>mess.</em></strong> Computers are supposed to make your life easier not harder. And Web apps are just one more way of doing that.
|
6
_content/A-day-in-the-life-of-Marzhill-Mu-2006-1-24.yml
Normal file
6
_content/A-day-in-the-life-of-Marzhill-Mu-2006-1-24.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: A day in the life of Marzhill Musings
|
||||||
|
time: 2006-01-24 14:45:58
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
Click below and see a cross section of my visiting poplutation<br /> <a href="/personal/1_24_06_grph.png"><img src='/personal/1_24_06_grph.png' alt='A day in the life of Marzhill Musings' width='300' height='192' /></a>
|
9
_content/A-look-at-an-old-favourite-2005-4-29.yml
Normal file
9
_content/A-look-at-an-old-favourite-2005-4-29.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
title: A look at an old favourite
|
||||||
|
time: 2005-04-29 02:45:06
|
||||||
|
tags:
|
||||||
|
- CSS
|
||||||
|
- User-Interface
|
||||||
|
- links
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
<a href="http://www.csszengarden.com/">css Zen Garden: The Beauty in CSS Design</a> I took a look at an old favourite today. CSS Zen Garden still makes me awestruck. I am overcome by an urge to create something beautiful. Yet feel small when I compare my efforts to them. If you ever want to look at beauty on the web then just visit the above link. If you ever want to see what good designers can do with standards based tools then look at the above link. Maybe someday I will have a submission featured there. Who knows, stranger things have happened. CSS is as much a part of WebApp development as javascript, html, or xml are. It is what gives you the power to put a face on your app. It makes standardizing the interface to your app easier and more comprehensible with it's inheritance and cascading abilities. When you build you apps don't forget the visual design or the visual designer. Give him the tools to create beautiful things. Like <a href="http://www.csszengarden.com/">here.</a>
|
6
_content/ABA-is-back-2006-5-1.yml
Normal file
6
_content/ABA-is-back-2006-5-1.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: ABA is back
|
||||||
|
time: 2006-05-01 15:15:47
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
<a href="http://ablogapart.com/">ABlogApart</a> a collection of folks with thoughtful commentary (or commentary at least). Is up and running again after a long hiatus. Drop by and meet the folks if you feel like it.
|
6
_content/According-to-Google-Analytics-2006-8-30.yml
Normal file
6
_content/According-to-Google-Analytics-2006-8-30.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: According to Google Analytics...
|
||||||
|
time: 2006-08-30 21:33:24
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
The subject that drives the most interesting traffic to this site is Apache2 with mod_perl2 questions. To that end after I finish this major software project on a mod_perl platform I intend to write up a more detailed tutorial on actually using mod_perl2 in a production environment and what it can do for you. So watch this space :-) I'll be done with the project before too long.
|
74
_content/Advanced-Nitrogen-Elements-2009-6-16.yml
Normal file
74
_content/Advanced-Nitrogen-Elements-2009-6-16.yml
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
title: Advanced Nitrogen Elements
|
||||||
|
time: 2009-06-16 23:33:58
|
||||||
|
tags:
|
||||||
|
- Site-News
|
||||||
|
- erlang
|
||||||
|
- javascript
|
||||||
|
- nitrogen
|
||||||
|
- tutorial
|
||||||
|
- web-framework
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
In my <a href="http://jeremy.marzhillstudios.com/index.php/site-news/creating-custom-nitrogen-elements/">last post</a> I walked you through creating a basic nitrogen element. In this one I'll be covering some of the more advanced topics in nitrogen elements. <ul> <li>Event handlers and delegation</li> <li>scripts and dynamic javascript postbacks</li> </ul> <h3>Nitrogen Event handlers</h3> Nitrogen event handlers get called for any nitrogen event. A nitrogen event is specified by assigning #event to an actions attribute of a nitrogen element. The event handler in the pages module will get called with the postback of the event. Postbacks are an attribute of the event record and define the event that was fired. To handle the event you create an event function in the target module that matches your postback. For Example:
|
||||||
|
<code syntax="erlang">
|
||||||
|
% given this event
|
||||||
|
#event{ type=click, postback={click, Id} }
|
||||||
|
% this event function would handle it
|
||||||
|
event({click, ClickedId}) ->
|
||||||
|
io:format("I [~p] was clicked", [ClickedId]) .
|
||||||
|
</code>
|
||||||
|
Erlangs pattern matching makes it especially well suited for this kind of event based programming. The one annoying limitation of this event though is that each page has to handle it individually. You could of course create a dispatching module that handled the event for you but why when nitrogen already did it for you. You can delegate an event to a specific module by setting the delegate attribute to the atom identifying that module.
|
||||||
|
<code syntax="erlang">
|
||||||
|
% delgated event
|
||||||
|
#event{ type=click, postback={click, Id}, delegate=my_module }
|
||||||
|
</code>
|
||||||
|
You can delgate to any module you want. I use the general rule of thumb that if the event affects other elements on the page then the page module should probably handle it. If, however, the event doesn't affect other elements on the page then the element's module can handle it. <h3>Scripts and Dynamic Postback</h3> Now lets get make it a little more interesting. Imagine a scenario where we want to interact with some javascript on a page and dynamically generate data to send back to nitrogen. As an example lets create a silly element that grabs the mouse coordinates of a click on the element and sends that back to nitrogen. A first attempt might look something like so:
|
||||||
|
<code syntax="erlang">
|
||||||
|
-record(silly, {?ELEMENT_BASE(element_silly)}). </code>
|
||||||
|
And the module is likewise simple:
|
||||||
|
<code syntax="erlang">
|
||||||
|
-module(element_silly).
|
||||||
|
-compile(export_all).
|
||||||
|
-include("elements.hrl").
|
||||||
|
-include_lib("nitrogen/include/wf.inc").
|
||||||
|
render(ControlId, R) ->
|
||||||
|
Id = wf:temp_id(),
|
||||||
|
%% wait!! where do we get the loc from?!
|
||||||
|
ClickEvent = #event{type=click, postback={click, Loc}}
|
||||||
|
Panel = #panel{id=Id, style="width:'100px' height='100px'",
|
||||||
|
actions=ClickEvent}, element_panel:render(Panel).
|
||||||
|
|
||||||
|
event({click, Loc}) ->
|
||||||
|
wf:update(body, wf:f("you clicked at point: ~s", Loc)).
|
||||||
|
</code>
|
||||||
|
Well of course you spot the problem here. Since the click happens client side we don't know what to put in the Loc variable for the postback. A typical postback won't work because the data will be generated in the client and not the Nitrogen server. So how could we get the value of the coordinates sent back? The javascript to grab the coordinates with jquery looks like this: <code syntax="javascript">
|
||||||
|
var coord = obj('me').pageX + obj('me').pageY;
|
||||||
|
</code> To plug that in to the click event is pretty easy since action fields in an event can hold other events or javascript or a list combining both:
|
||||||
|
<code syntax="erlang">
|
||||||
|
Script = "var coord = obj('me').pageX + obj('me').pageY;",
|
||||||
|
ClickEvent = #event{type=click, postback={click, Loc}, actions=Script}
|
||||||
|
</code>
|
||||||
|
Now we've managed to capture the coordinates of the mouse click, but we still haven't sent it back to the server. This javascript needs a little help. What we need is a drop box. Lets enhance our element with a few helpers:
|
||||||
|
<code syntax="erlang">
|
||||||
|
-module(element_silly).
|
||||||
|
-compile(export_all).
|
||||||
|
-include("elements.hrl").
|
||||||
|
-include_lib("nitrogen/include/wf.inc").
|
||||||
|
render(ControlId, R) ->
|
||||||
|
Id = wf:temp_id(),
|
||||||
|
DropBoxId = wf:temp_id(),
|
||||||
|
MsgId = wf:temp_id(),
|
||||||
|
Script = wf:f("var coord = obj('me').pageX + obj('me').pageY; $('~s').value = coord;",
|
||||||
|
[DropBoxId]),
|
||||||
|
ClickEvent = #event{type=click, postback={click, Id, MsgId},
|
||||||
|
actions=Script},
|
||||||
|
Panel = #panel{id=Id, style="width:'100px'; height='100px'",
|
||||||
|
actions=ClickEvent, body=[#hidden{id=DropBoxId},
|
||||||
|
#panel{id=MsgId}]},
|
||||||
|
element_panel:render(Panel).
|
||||||
|
|
||||||
|
event({click, Id, Msg}) ->
|
||||||
|
Loc = hd(wf:q(Id)),
|
||||||
|
wf:update(Msg, wf:f("you clicked at point: ~s", Loc)).
|
||||||
|
</code>
|
||||||
|
Ahhh there we go. Now our element when clicked will: <ol> <li>use javascript to grab the coordinates of the mouse click</li> <li>use javascript to store those coordinates in the hidden element</li> <li>use a postback to send the click event back to a nitrogen event handler with the id of the hidden element where it stored the coordinates.</li> </ol> We have managed to grab dynamically generated data from the client side and drop it somehwere that nitrogen can retrieve it. In the process we have used an event handler, custom javascript, and dynamic javascript postbacks. <strong>Edit</strong>: Corrected typo - June 16, 2009 at 11:40 pm
|
6
_content/All-for-lack-of-a-plug-2005-5-3.yml
Normal file
6
_content/All-for-lack-of-a-plug-2005-5-3.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: All for lack of a plug
|
||||||
|
time: 2005-05-03 00:06:25
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
The site was down last evening again. Someone unplugged the network cable. I'm not sayin who, but he was short and his name starts with a T. Anyway the server is now located in a safer environment where such things should no longer occur. (<em>and T has received a strong lecture on unplugging strange cords</em>)
|
6
_content/App-VS-Page-2005-4-11.yml
Normal file
6
_content/App-VS-Page-2005-4-11.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: App VS. Page
|
||||||
|
time: 2005-04-11 22:49:33
|
||||||
|
section: Software-Development
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
Software Development on the Web is undergoing a revolution. We've had the ability to build responsive, useable, dynamic applications for quite a while now. But no one has capitalized on it. No one has been building those applications. Most web developers are still stuck in the WebPage mode of design and not the WebApp mode of design. Thankfully, companies like Google are starting to give the WebApp design philosophy some high profile attention with apps like <a href="http://gmail.google.com">Gmail</a> and <a href="http://maps.google.com/">Google Maps</a>. So what exactly is the difference? There are a number of radical differences between WebApp and WebPage Design modes. Each has a use in website designing. Webpage Design is about presenting information. It focuses on making the content readable, understandable, and locatable. Reference sites, and online literature sites do well with this design philosophy. Blogs are another instance where the WebPage Design philosophy works well. \ WebApp Design, on the other hand, focuses on responsive, dynamic, <strong>realtime</strong> action. Sites that allow the user to <strong>do</strong> something benefit the most from this approach. The Administration front ends to Reference sites, a WebMail site, and Online Game sites are all excellent candidates for the web app approach to design. Elements of these approaches to design are now getting combined in interesting ways. Google's autocomplete feature is one example. A melding of the two can only be beneficial to Web Development trends. In future articles I will be talking about some of the technologies that make these trends possible.
|
8
_content/Are-You-a-Data-Middle-Man?-2006-1-17.yml
Normal file
8
_content/Are-You-a-Data-Middle-Man?-2006-1-17.yml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
title: Are You a Data Middle Man?
|
||||||
|
time: 2006-01-17 16:29:22
|
||||||
|
tags:
|
||||||
|
- Data
|
||||||
|
- Software-Development
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
Not too long ago, before the bubble burst as they say, one of the HOT new things was B2B technology. Hooking businesses together for their mutual profit. You don't hear a whole lot about that anymore. I think probably because those companies lost their focus and consequently never made any money. You see the real power of the "network" is in sharing data. B2B really was all about sharing that data. If you could emphasize that feature you could have made money. Becoming the middle guy in the selling and purchasing of data could become a very powerful and lucrative business. Especially since the new "emphasis" on standards is helping the process along. If you look at a lot of the hottest things in the web right now they all talk about sharing data of some sort. Flikr, Techdirt, Blog aggregators. All of them provide ways to access and share their data easily. And the investors are salivating. Notice I said "their" data. If you never have data to share no one uses your API/Standard. The reality is that Standards only work if someone shows you how to use them and uses them themselves. The Data Middle Men are the ones who will define these standards of exchange. They will be brokering the transfers and more importantly providing the infrastructure for those transfer. I've been thinking about this a lot lately because one of my customers has an opportunity to become one of the first of the Homecare Data Middle Men. It's gonna be a fun and wild ride :-)
|
6
_content/Bear-with-me-2005-6-26.yml
Normal file
6
_content/Bear-with-me-2005-6-26.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Bear with me
|
||||||
|
time: 2005-06-26 06:07:53
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
I'm renovating. You may run across some different styles popping up every once and a while. I'm still figuring out how this wordpress themes thing works so there may be a some bumps in the road along the way.
|
8
_content/Beauty-Artistry-and-computer-c-2006-2-21.yml
Normal file
8
_content/Beauty-Artistry-and-computer-c-2006-2-21.yml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
title: Beauty, Artistry, and computer code.
|
||||||
|
time: 2006-02-21 10:08:57
|
||||||
|
tags:
|
||||||
|
- Site-News
|
||||||
|
- Software-Development
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
I'd like to take a moment to wax poetic. Code hackers have a term for well written code. Elegant. We appreciate elegant design and algorithms in code. It's a pleasure to work on code like that. We will stop and just think "Man, that's beautiful" Even our quick and dirty scripts somehow turn out to be pieces of art. So what makes a piece of code beautiful? It's a little bit hard to describe but there are usually several elements that contribute to code's beauty. Those elements that compose what I perceive as beauty in code are: <ul> <li>Efficiency</li> <li>Cleverness</li> <li>Style</li> <li>Flow</li> </ul> <strong>Efficiency</strong> Efficiency is perhaps one of the most important elements in the percieved beauty of code. Code that is streamlined, sleek, and targetted is beautiful. This kind of code does one thing and does it well. There is no wasted effort or duplicated work in efficient code. Efficient code knows what it needs to do and gets down to business. Many times this equates to less code though not always. <strong>Cleverness</strong> Cleverness is a close second in the elements of code beauty list. Cleverness as defined by "Now, that's a <em>cool</em> way to do it!!" It's coming up with a better and heretofore unconsidered method or algorithm to get the job done. It's similar to those paintings in art with surprise built into them. Like the excercises in perspective where you don't realize it's a painting till you get close. It makes you stop and go Wow! Now that's cool. Code cleverness usually has a lot to do with Efficiency. If your clever hack makes the code less efficient it may actually decrease your codes beauty. It can be a double edged sword. <strong>Style</strong> Style along with Flow are the subjective parts of the beauty equation. It means different things to different people. It's part of what makes someone love perl and hate python while a different person loves python and hates perl. Style encompasses such things Indenting, code organization, and naming conventions. Everyone has a different opinion of what looks good. Similar to art where one person likes modern art and another thinks it looks ridiculous. <strong>Flow</strong> Flow is also a highly subjective part of the beauty equation. Some people like to flowchart for days before even touching the keyboard. Others prefer to let the programs logic structure sort of organically grow. Still others prefer a balance somewhere between the two. Flow covers how your code handles the various tasks that it is responsible for. It encompasses reusability. And it can increase or decrease your code's efficiency. Like Art everyone has their own definition of what is beauty when it comes to Flow. So how do you classify beautiful code? Let me know in the comments.
|
6
_content/Beryl-Scale-Plugin-2007-2-15.yml
Normal file
6
_content/Beryl-Scale-Plugin-2007-2-15.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Beryl Scale Plugin
|
||||||
|
time: 2007-02-15 15:31:00
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
The Beryl Scale window selection plugin
|
6
_content/Beryl-XGL-The-CUBE-2007-2-22.yml
Normal file
6
_content/Beryl-XGL-The-CUBE-2007-2-22.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Beryl/XGL The CUBE....
|
||||||
|
time: 2007-02-22 16:37:57
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
I'm not sure how useful this actually is but you can't deny that it's pretty cool. May I present to you the Cube: <a class="imagelink" href="http://jeremy.marzhillstudios.com/wp-content/uploads/2007/02/Cube3D_Windows.png" title="Desktop Cube"><img id="image122" src="http://jeremy.marzhillstudios.com/wp-content/uploads/2007/02/Cube3D_Windows.thumbnail.png" alt="Desktop Cube" /></a> Now, like all the things Beryl can do, this is in realtime so you can watch progress bars move, text scroll, and movies play all while rotating your cube.
|
6
_content/Beryl-XGL-Transparency-and-Thumb-2007-2-14.yml
Normal file
6
_content/Beryl-XGL-Transparency-and-Thumb-2007-2-14.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Beryl/XGL Transparency and Thumbnailing
|
||||||
|
time: 2007-02-14 13:48:20
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
Beryl allows you to do realtime transparency and thumbnailing with windows. The following screenshot demonstrates these capabilities. There is a video playing underneath a transparent window and also playing on the thumbnail of the window over the taskbar. Unfortunately you can not see the video actually playing in the thumbnail and underneath the transparent window so you'll have to take my word for it. Its a powerful demonstration of how powerful the Beryl/XGL architecture can be. <a class="imagelink" href="http://jeremy.marzhillstudios.com/wp-content/uploads/2007/02/ThumnailingAndTransparency.png" title="Transparency and Thumbnailing"><img id="image118" src="http://jeremy.marzhillstudios.com/wp-content/uploads/2007/02/ThumnailingAndTransparency.thumbnail.png" alt="Transparency and Thumbnailing" /></a>
|
6
_content/Beryl-XGL-the-Scale-plugin-2007-2-15.yml
Normal file
6
_content/Beryl-XGL-the-Scale-plugin-2007-2-15.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Beryl/XGL the Scale plugin
|
||||||
|
time: 2007-02-15 15:32:10
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
A particularly handy feature of Beryl is the Scale Plugin. This plugin gives an easy intuitive way to select the window you want to switch to on a busy desktop. It can be activated by setting a hotspot or using a hotkey. It takes all the open windows and tiles them in the screen scaling them to fit so you can pick the window you want to switch to easily. It also displays those windows in realtime so video keeps playing commandline console text keeps scrolling and so on. Here is a screenshot of this feature: <a class="imagelink" href="http://jeremy.marzhillstudios.com/wp-content/uploads/2007/02/Scale.png" title="Beryl Scale Plugin"><img id="image120" src="http://jeremy.marzhillstudios.com/wp-content/uploads/2007/02/Scale.thumbnail.png" alt="Beryl Scale Plugin" /></a>
|
6
_content/BerylTabbing-2007-2-13.yml
Normal file
6
_content/BerylTabbing-2007-2-13.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: BerylTabbing
|
||||||
|
time: 2007-02-13 12:40:45
|
||||||
|
tags: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
Two windows Tabbed for grouping in Beryl
|
6
_content/Bill-Gates-He-eats-his-own-dogf-2006-4-6.yml
Normal file
6
_content/Bill-Gates-He-eats-his-own-dogf-2006-4-6.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Bill Gates. He eats his own dogfood.
|
||||||
|
time: 2006-04-06 09:09:26
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
Bill Gates the man behind Microsoft. Has published an interview with CNN on how he works. At the article: <a href="http://money.cnn.com/2006/03/30/news/newsmakers/gates_howiwork_fortune/index.htm">Bill Gates - How I work</a> on money.cnn.com. Some of it no doubt is more advertising than informative however it is nice to see someone who actually uses what his company produces. The problem with Microsoft nowadays isn't the quality of their products. It's the price and the licensing. Microsoft has some great integrations in their products. If you can afford to purchase the sharepoint servers, Latest Office version, all the little office addons, and keep em up to date then by all means your office can experience a lot of internal productivity. The thing about Bill's job though is that he doesn't have to worry about incompatibilities within his organization or when dealing with other companies. Microsoft always has the latest versions of everything internally. Bill works in sort of an ivory tower where everything just works because they write the software. Out there in the real world though Microsoft is losing a very important battle. They are still fighting to keep things a Microsoft world. But the Genie is out of the bottle and eventually they will have to begin supporting open standards with no catches. People will stop caring about the nifty new feature if they can't use them anywhere they want on any platform. Microsoft in point of fact can't depend on everyone's work place being like microsofts anymore. I wonder what happens when Bill gets an email back saying: "Im sorry but we can't read your office 200x document please resend it in an open format like ODF, Plain Text, or RTF. Thank you." That day is coming we may not know when and I'm not stupid enough to try to predict it. but it is coming. The free market is running like it's supposed too and Microsoft is in for a rude awakening if they don't start preparing for it. Keep an eye on Minnesota. I have a feeling this trend we are seeing may accelerate exponentially.
|
9
_content/Blender:-Its-more-than-a-modell-2007-3-12.yml
Normal file
9
_content/Blender:-Its-more-than-a-modell-2007-3-12.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
title: Blender - It's more than a modeller
|
||||||
|
time: 2007-03-12 23:00:55
|
||||||
|
tags:
|
||||||
|
- Site-News
|
||||||
|
- Open-Source
|
||||||
|
- OSS-Apps
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
Blender is known as the most complete Open Source 3D modeller out there for open source. It also has a reputation for being one of those love it or hate it software packages with a steep learning curve. Blender is more than just a 3d content creation package though. It also happens to be perhaps the best video compositing and Non Linear editor available for open source. Cinelerra has a lot of power but isn't particularly great when you need to do a lot of keyframing. Jahshaka has a lot of potential but is unstable and still has a long way to go. Kino only does Digital video. But blender?.. Blender has it all. Blender is quite possibly the only package that gives you an end to end solution for content creation. What can blender do for you as a video editor? Well Just about anything actually. In can composite images and video/animations. It has a non linear video editor. It has an audio seqencer. In just under an hour I did the following short video clip using three still images. <a href="http://jeremy.marzhillstudios.com/personal/artwork/CompExamples0001_0120.mp4">Compositing Still Image Test Video</a> Blender has introduced node based compositing and as of 2.43 it has become quite powerful in that arena. The .blend file to do the effects seen above can be downloaded here. Hopefully it will show you some of the power that blender can bring to a video production pipeline.
|
13
_content/BrickLayer-RC1-2005-11-19.yml
Normal file
13
_content/BrickLayer-RC1-2005-11-19.yml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
title: BrickLayer RC1
|
||||||
|
time: 2005-11-19
|
||||||
|
timeformat: 2006-01-02
|
||||||
|
tags:
|
||||||
|
- Site-News
|
||||||
|
- APIs
|
||||||
|
- BrickLayer
|
||||||
|
- Languages
|
||||||
|
- Perl
|
||||||
|
- Software-Development
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
My first release of BrickLayer. is ready. I'm still writing some of the documentation, but I couldn't resist giving you a peek. You can get it here: <a href="http://jeremy.marzhillstudios.com/bricklayer/BrickLayer_RC1.tar.gz">BrickLayer</a> And here is the documentation I have written so far: <a href="http://jeremy.marzhillstudios.com/bricklayer/UsingBrickLayer.html">Using BrickLayer</a> <a href="http://jeremy.marzhillstudios.com/bricklayer/BrickLayerTemplating.html">BrickLayer Templating</a> <a href="http://jeremy.marzhillstudios.com/bricklayer/BricklayerPluginDevelopment.html">BrickLayer Plugin Development</a> The BrickLayer DB Interface documentation is in progress.
|
10
_content/BrickLayer-RC2-is-out-2006-1-25.yml
Normal file
10
_content/BrickLayer-RC2-is-out-2006-1-25.yml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
title: BrickLayer RC2 is out
|
||||||
|
time: 2006-01-25 13:41:38
|
||||||
|
tags:
|
||||||
|
- Site-News
|
||||||
|
- BrickLayer
|
||||||
|
- Perl
|
||||||
|
- Software-Development
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
<a href='/personal/BricklayerRC2.tar.gz' title='Bricklayer RC2'>Bricklayer RC2</a> Download it while it's hot. I have added a number of bugfixes and enhancements. But it's still in testing so don't plan on using this in a production environment yet :-)
|
6
_content/Bricklayer-Documenation-Update-2006-8-22.yml
Normal file
6
_content/Bricklayer-Documenation-Update-2006-8-22.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Bricklayer Documenation Update
|
||||||
|
time: 2006-08-22 12:23:49
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
I've revamped and rewritten the Bricklayer documentation to reflect some significant changes to the API. You can get it off the <a href="http://sourceforge.net/projects/bricklayer-perl">Sourceforge site</a> or <a href="http://jeremy.marzhillstudios.com/bricklayer/BKManual/">browse it online here</a> using the link on the menu. Please let me know if you find any errors in spelling grammar or the API description. Also if there is any additional information you might want included in it.
|
10
_content/Bricklayer-RC21-2006-2-8.yml
Normal file
10
_content/Bricklayer-RC21-2006-2-8.yml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
title: Bricklayer RC2.1
|
||||||
|
time: 2006-02-08 23:55:44
|
||||||
|
tags:
|
||||||
|
- Site-News
|
||||||
|
- APIs
|
||||||
|
- BrickLayer
|
||||||
|
- Perl
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
<a href="http://jeremy.marzhillstudios.com/bricklayer/BrickLayerRC2.1.tar.gz">BrickLayer RC2.1</a> Bugfix and modifications to the Bricklayer RC2 release. Accompanied by <a href="http://jeremy.marzhillstudios.com/bricklayer/BKManual/">amended documentation.</a>
|
11
_content/Bricklayer-Refactored-and-other-2007-1-16.yml
Normal file
11
_content/Bricklayer-Refactored-and-other-2007-1-16.yml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
title: Bricklayer Refactored and other news
|
||||||
|
time: 2007-01-16 23:42:54
|
||||||
|
tags:
|
||||||
|
- APIs
|
||||||
|
- BrickLayer
|
||||||
|
- Open-Source
|
||||||
|
- Perl
|
||||||
|
- Software-Development
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
Bricklayer has been heavily refactored for more modularity. You can see the much changed codebase at the new <a href="http://bricklayer-perl.svn.sourceforge.net/viewvc/bricklayer-perl/Current/">svn repository</a> Instructions for SVN Checkout can be found here: <a href="http://sourceforge.net/svn/?group_id=173287">SourceForge SVN Checkout</a> Current is the trunk branch in the repository tree structure. Documentation and some examples for the new API will be forthcoming shortly. Including the new DataBase Access API concept I will be introducing. A preview of the proof of concept code is in the Bricklayer/Data libraries directory.
|
11
_content/Bricklayer-Subversion-Repository-2006-1-30.yml
Normal file
11
_content/Bricklayer-Subversion-Repository-2006-1-30.yml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
title: Bricklayer Subversion Repository is up
|
||||||
|
time: 2006-01-30 10:27:57
|
||||||
|
tags:
|
||||||
|
- Site-News
|
||||||
|
- APIs
|
||||||
|
- BrickLayer
|
||||||
|
- Perl
|
||||||
|
- Software-Development
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
I have finished moving my bricklayer subversion source code repository to a public location. you can find it at the following link. If your browser recognizes the svn protocol you can just click the link below. For all others you'll need to copy the link location into a subversion browser of some sort. Now you can get the cutting edge copy :-) enjoy!! <a href="svn://marzhillstudios.com/repos/bricklayer/Current">BrickLayer Subversion Repository</a>
|
6
_content/Bricklayer-is-Coming-2005-11-16.yml
Normal file
6
_content/Bricklayer-is-Coming-2005-11-16.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Bricklayer is Coming....
|
||||||
|
time: 2005-11-16 23:18:49
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
<div style="text-align: center;"> <img src='/personal/Logo_large.png' alt='BrickLayer Logo' /> Details to follow.</div>
|
6
_content/Bricklayer-is-on-Sourceforge-2006-7-27.yml
Normal file
6
_content/Bricklayer-is-on-Sourceforge-2006-7-27.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Bricklayer is on Sourceforge
|
||||||
|
time: 2006-07-27 21:26:31
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
<a href="http://sourceforge.net/projects/bricklayer-perl/">SourceForge project page</a> Have a look if you want.
|
6
_content/Bricklayer::Templater-is-getting-2007-7-14.yml
Normal file
6
_content/Bricklayer::Templater-is-getting-2007-7-14.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: "Bricklayer::Templater is getting unit tests"
|
||||||
|
time: 2007-07-14 19:16:38
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
Yay I'm finally getting around to it and boy is it a good thing. The code is already benefitting from it. I'll be uploading some stuff to the sourceforge svn repository soon so stay tuned.
|
12
_content/Bricklayer::Templater-is-on-CPAN-2007-8-14.yml
Normal file
12
_content/Bricklayer::Templater-is-on-CPAN-2007-8-14.yml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
title: "Bricklayer::Templater is on CPAN"
|
||||||
|
time: 2007-08-14 16:20:30
|
||||||
|
tags:
|
||||||
|
- Site-News
|
||||||
|
- APIs
|
||||||
|
- BrickLayer
|
||||||
|
- Open-Source
|
||||||
|
- Perl
|
||||||
|
- Software-Development
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
And I have registered its namespace so it shows up in the module list. This means the Bricklayer::* namespace can now be used to begin build the various components of my evolving frameworks <a href="http://search.cpan.org/~zaphar/">Bricklayer::Templater</a>
|
167
_content/Creating-Custom-Nitrogen-Element-2009-5-22.yml
Normal file
167
_content/Creating-Custom-Nitrogen-Element-2009-5-22.yml
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
title: Creating Custom Nitrogen Elements
|
||||||
|
time: 2009-05-22 19:05:57
|
||||||
|
tags:
|
||||||
|
- Site News
|
||||||
|
- ajax
|
||||||
|
- erlang
|
||||||
|
- event driven
|
||||||
|
- nitrogen
|
||||||
|
- tutorial
|
||||||
|
- functional
|
||||||
|
- web framework
|
||||||
|
section: coding
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
<a href="http://github.com/rklophaus/nitrogen/tree/master">Nitrogen</a> is a web framework written in erlang for Fast AJAX Web applications. You can get <a href="http://github.com/rklophaus/nitrogen/tree/master">Nitrogen on github</a> Nitrogen comes with a set of useful controls, or elements in nitrogen parlance, but if you are going to do anything more fancy than a basic hello world you probably want to create some custom controls. This tutorial will walk you through the ins and outs of writing a custom element for Nitrogen. We will be creating a simple notification element similar to one I use in the Iterate! project. It will need to be able to: <ul> <li> show a message</li> <li>have a way to dismiss it</li> <li> and optionally expire and disappear after a configurable period of time</li> </ul> Every Nitrogen element has two main pieces: the Record and the Module. I'll go through each in order and walk you through creating our notification element. <h2>The Record</h2> The record defines all the state required to create a nitrogen element. Every record needs a certain base set of fields. These fields can be added to your record with the ?ELEMENT_BASE macro. The macro is available in the nitrogen include file wf.inc. That include file also gives you access to all the included nitrogen element records. Below you can see the record definition for our notify element. Since it is very simple in it's design it only needs the base elements and two additional fields. expire to handle our optional expiration time and default to false to indicate no expiration. msg to hold the contents of our notification.
|
||||||
|
<pre syntax="erlang">
|
||||||
|
%Put this line in an include file for your elements
|
||||||
|
-record(notify, {?ELEMENT_BASE(element_notify), expire=false, msg}).
|
||||||
|
</pre>
|
||||||
|
<pre syntax="erlang">
|
||||||
|
% put these at the top of your elements module
|
||||||
|
-include_lib("nitrogen/include/wf.inc").
|
||||||
|
% the above mentioned include file you may call it whatever you want
|
||||||
|
-include("elements.inc").
|
||||||
|
</pre>
|
||||||
|
The ELEMENT_BASE macro gives your element several fields and identifies for the element which module handles the rendering of your nitrogen element. You can specify any module you want but the convention is to name the module with element_element_name. The fields provided are: id, class, style, actions, and show_if. You can use them as you wish when it comes time to render your element. Which brings us to the module. <h2>The Module</h2> Of the two pieces of a nitrogen element the module does the manual labor. It renders and in some cases defines the handlers for events fired by the element. The module must export a render/2 function. This function will be called whenever nitrogen needs to render a particular instance of your element. It's two arguments are: The ControlId, and the Record defining this element instance. Of these the ControlID is probably the least understood. It is passed into your render method by nitrogen and is the assigned HTML Id for your particular element. This is important to understand because, when you call the next render method in your elements tree, you will have to pass an ID on. The rule of thumb I use is that if you want to use a different Id for your toplevel element then you can ignore the ControlId. Otherwise you should use it as the id for your toplevel element in the control. So your element's module should start out with something like this:
|
||||||
|
<pre syntax="erlang">
|
||||||
|
-module(element_notify).
|
||||||
|
-compile(export_all).
|
||||||
|
-include_lib("nitrogen/include/wf.inc").
|
||||||
|
-include("elements.hrl").
|
||||||
|
% give us a way to inspect the fields of this elements record
|
||||||
|
% useful in the shell where record_info isn't available
|
||||||
|
reflect() -> record_info(fields, notify).
|
||||||
|
% Render the custom element
|
||||||
|
render(ControlId, R) ->
|
||||||
|
% get a temp id for our notify element instance
|
||||||
|
Id = ControlId,
|
||||||
|
% Our toplevel of the element will be a panel (div)
|
||||||
|
Panel = #panel{id=Id},
|
||||||
|
% the element_panel module is used to render the panel element
|
||||||
|
element_panel:render(Id, Panel),
|
||||||
|
% Or use the alternative method:
|
||||||
|
Module = Panel#panel.module,
|
||||||
|
Module:render(Id, Panel).
|
||||||
|
</pre>
|
||||||
|
Notice that the records module attribute tells us what module we should call to render the element in the alternative method. In our case we will just hardcode the module since it's known to us. So now we have a basic element that renders a div with a temp id to our page. That's not terribly useful though. We actually need this element to render our msg, and with some events attached. Lets add the code to add our message to the panels contents.
|
||||||
|
<pre syntax="erlang">
|
||||||
|
Panel = #panel{id=Id, body=R#notify.msg},
|
||||||
|
element_panel:render(ControlId, Panel)
|
||||||
|
</pre>
|
||||||
|
Now whatever is in the msg attribute of our notify record will be in the body of the panel when it gets rendered. All we need is a way to dismiss it. A link should do the trick. But now we have a slight problem. In order to add our dismiss link we need to add it to the body of the Panel. but the msg is already occupying that space. We could use a list and prepend the link to the end of the list for the body but that doesn't really give us a lot of control over styling the element. what we really need is for the msg to be in an inner panel and the outer panel will hold any controls the element needs.
|
||||||
|
<pre syntax="erlang">
|
||||||
|
Link = #link{text="dismiss"},
|
||||||
|
InnerPanel = #panel{body=R#notify.msg},
|
||||||
|
Panel = #panel{id=Id, body=[InnerPanel,Link]},
|
||||||
|
element_panel:render(ControlId, Panel)
|
||||||
|
</pre>
|
||||||
|
Our link doesn't actually dismiss the notification yet though. To add that we need to add a click event to the link. Nitrogen has a large set of events and effects available. You can find them . We will be using the click event and the hide effect.
|
||||||
|
<pre syntax="erlang">
|
||||||
|
Event = #event{type=click,
|
||||||
|
actions=#hide{effect=blind, target=Id}},
|
||||||
|
Link = #link{text="dismiss", actions=Event},
|
||||||
|
</pre>
|
||||||
|
Now our module should look something like this:
|
||||||
|
<pre syntax="erlang">
|
||||||
|
-module(element_notify).
|
||||||
|
-compile(export_all).
|
||||||
|
-include_lib("nitrogen/include/wf.inc").
|
||||||
|
-include("elements.hrl").
|
||||||
|
% give us a way to inspect the fields of this elements record
|
||||||
|
% useful in the shell where record_info isn't available
|
||||||
|
reflect() -> record_info(fields, notify).
|
||||||
|
% Render the custom element
|
||||||
|
render(ControlId, R) ->
|
||||||
|
% get a temp id for our notify element instance
|
||||||
|
Id = ControlId,
|
||||||
|
% Our toplevel of the element will be a panel (div)
|
||||||
|
Event = #event{type=click, actions=#hide{effect=blind, target=Id}},
|
||||||
|
Link = #link{text="dismiss", actions=Event},
|
||||||
|
InnerPanel = #panel{body=R#notify.msg},
|
||||||
|
Panel = #panel{id=Id, body=[InnerPanel,Link]},
|
||||||
|
% the element_panel module is used to render the panel element
|
||||||
|
element_panel:render(Id, Panel).
|
||||||
|
</pre>
|
||||||
|
This is a fully functional nitrogen element. But it's missing a crucial feature to really shine. Our third feature for this element was an optional expiration for the notification. Right now you have to click dismiss to get rid of the element on the page. But sometimes we might want the element to go away after a predetermined time. This is what our expire record field is meant to determine for us. There are three possible cases for this field. <ul> <li>set to false (the default)</li> <li>set to some integer (the number of seconds after which we want to go away)</li> <li>set to anything else (the error condition)</li> </ul> This is the kind of thing erlang's case statement was made for:
|
||||||
|
<pre syntax="erlang">
|
||||||
|
case R#notify.expire of
|
||||||
|
false ->
|
||||||
|
undefined;
|
||||||
|
N when is_integer(N) ->
|
||||||
|
% we expire in this many seconds
|
||||||
|
wf:wire(Id, #event{type='timer', delay=N, actions=#hide{effect=blind, target=Id}});
|
||||||
|
_ ->
|
||||||
|
% log error and don't expire
|
||||||
|
undefined
|
||||||
|
end
|
||||||
|
</pre>
|
||||||
|
Notice the wf:wire statement. wf:wire is an alternate way to add events to a nitrogen element. Just specify the id and then the event record/javascript string you want to use. I've noticed that for events of type timer wf:wire works better than assigning them to the actions field of the event record. No idea why because I have not looked into it real closely yet. Now our module looks like this:
|
||||||
|
<pre syntax="erlang">
|
||||||
|
-module(element_notify).
|
||||||
|
-compile(export_all).
|
||||||
|
-include_lib("nitrogen/include/wf.inc").
|
||||||
|
-include("elements.hrl").
|
||||||
|
% give us a way to inspect the fields of this elements record
|
||||||
|
% useful in the shell where record_info isn't available
|
||||||
|
reflect() ->record_info(fields, notify).
|
||||||
|
% Render the custom element
|
||||||
|
render(_, R) ->
|
||||||
|
% get a temp id for our notify element instance
|
||||||
|
Id = ControlId,
|
||||||
|
% Our toplevel of the element will be a panel (div)
|
||||||
|
case R#notify.expire of
|
||||||
|
false ->
|
||||||
|
undefined;
|
||||||
|
N when is_integer(N) ->
|
||||||
|
% we expire in this many seconds
|
||||||
|
wf:wire(Id, #event{type='timer', delay=N, actions=#hide{effect=blind, target=Id}});
|
||||||
|
_ ->
|
||||||
|
% log error and don't expire
|
||||||
|
undefined
|
||||||
|
end,
|
||||||
|
Event = #event{type=click, actions=#hide{effect=blind, target=Id}},
|
||||||
|
Link = #link{text="dismiss", actions=Event},
|
||||||
|
InnerPanel = #panel{body=R#notify.msg},
|
||||||
|
Panel = #panel{id=Id, body=[InnerPanel,Link]},
|
||||||
|
% the element_panel module is used to render the panel element
|
||||||
|
element_panel:render(ControlId, Panel).
|
||||||
|
</pre>
|
||||||
|
We have now fulfilled all of our criteria for the element. It shows a message of our choosing. It can be dismissed with a click. And it has an optional expiration. One last thing to really polish it off though would to allow styling through the use of css classes. The ELEMENT_BASE macro we used in our record definition gives our element a class field. We can use that to set our Panel's class, allowing any user of the element to set the class as they wish like so:
|
||||||
|
<pre syntax="erlang">
|
||||||
|
Panel = #panel{id=Id, class=["notify ", R#notify.class],
|
||||||
|
body=[InnerPanel,Link]},
|
||||||
|
</pre>
|
||||||
|
This gives us the final module for our custom element:
|
||||||
|
<pre syntax="erlang">
|
||||||
|
-module(element_notify).
|
||||||
|
-compile(export_all).
|
||||||
|
-include_lib("nitrogen/include/wf.inc").
|
||||||
|
-include("elements.hrl").
|
||||||
|
% give us a way to inspect the fields of this elements record
|
||||||
|
% useful in the shell where record_info isn't available
|
||||||
|
reflect() -> record_info(fields, notify).
|
||||||
|
% Render the custom element
|
||||||
|
render(_, R) ->
|
||||||
|
% get a temp id for our notify element instance
|
||||||
|
Id = ControlId,
|
||||||
|
% Our toplevel of the element will be a panel (div)
|
||||||
|
case R#notify.expire of
|
||||||
|
false ->
|
||||||
|
undefined;
|
||||||
|
N when is_integer(N) ->
|
||||||
|
% we expire in this many seconds
|
||||||
|
wf:wire(Id, #event{type='timer', delay=N, actions=#hide{effect=blind, target=Id}});
|
||||||
|
_ ->
|
||||||
|
% log error and don't expire
|
||||||
|
undefined
|
||||||
|
end,
|
||||||
|
Event = #event{type=click, actions=#hide{effect=blind, target=Id}},
|
||||||
|
Link = #link{text="dismiss", actions=Event},
|
||||||
|
InnerPanel = #panel{body=R#notify.msg},
|
||||||
|
Panel = #panel{id=Id, class=["notify ", R#notify.class],
|
||||||
|
body=[InnerPanel,Link]},
|
||||||
|
% the element_panel module is used to render the panel element
|
||||||
|
element_panel:render(ControlId, Panel).
|
||||||
|
</pre>
|
||||||
|
I will cover delegated events and more advanced topics in a later tutorial.
|
6
_content/Creation-Programming-and-Easte-2006-3-27.yml
Normal file
6
_content/Creation-Programming-and-Easte-2006-3-27.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Creation, Programming, and Easter Eggs
|
||||||
|
time: 2006-03-27 11:23:04
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
In programming we have the term Easter Egg. It refers to hidden functionality in an application. Many times hidden even from the management. Some of you may remember the famous pinball game or Flight simulator hidden in the Office 97 Apps. Games are another popular place for programmers to hide Easter Eggs. They are kind of the Programmers little joke for the User of their software. Easter Eggs are fun and can really brighten a dull day. Some of you may know that I consider programming a creative art. In fact I consider some programming to be not unlike painting or writing poetry. For those who think like that, Easter eggs are like those hidden messages artists will sometimes hide in a painting. If you know me very well you will also know I'm a christian. I believe our capacity to create and enjoy beauty and surprise are a trait that comes from being made in Gods Image. When you think about it Creating the Universe was kind of like programming a work of art. God is the ultimate Hacker. He encoded the biology of whole Species into a few strands of DNA. He wrote the rules of Physics, and designed how Numbers work. His code is so beautiful it would move Linus Torvalds himself to tears. And like many coders I think God added a few Easter Eggs to his work. So the next time you hear of some funny coincidence that just strikes you as a little odd and somehow funny just imagine God in the beginning of Time turning to the Holy Spirit and saying "Wait till they get a load of this one..."
|
6
_content/Data::Annotated-and-Class::Data:-2007-8-27.yml
Normal file
6
_content/Data::Annotated-and-Class::Data:-2007-8-27.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: "Data::Annotated and Class::Data::Annotated"
|
||||||
|
time: 2007-08-27 16:43:45
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
So I've added two new modules to my CPAN repertoire. Data::Annotated and Class::Data::Annotated. Data::Annotated is a module intended to hold an annotation about a piece of a data structure independently of the Data::Structure itself. The annotation can be anything a hash an array or a scalar value. The piece of the data structure is referenced by a Data::Path. Class::Data::Annotated wraps a perl data structure and an associated set of annotations together in one place. I've also added to Data::Path's functionality so that it can annotate object methods and coderefs stored in a data structure. Once I've ironed out details with the original author I'll hopefully be uploading that. Anyway feel free to check them out: <a href="http://search.cpan.org/~zaphar/">My CPAN Libraries</a>
|
8
_content/Debugging-Axiom-#1-2007-2-28.yml
Normal file
8
_content/Debugging-Axiom-#1-2007-2-28.yml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
title: Debugging Axiom #1
|
||||||
|
time: 2007-02-28 13:02:04
|
||||||
|
tags:
|
||||||
|
- Site-News
|
||||||
|
- Software-Development
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
There is an axiom coined I believe by Sir Arthur Conan Doyle in his Sherlock Holmes novels that every programmer should keep in mind while debugging his program. <blockquote>When you have eliminated every other possibility; Whatever is left, however improbable, Must be the Solution.</blockquote> There has been many a time when I could have arrived at the answer much sooner but was stuck because what the program was doing seemed to be impossible. When I accepted that it was possible then I was able to begin tracking down how it was possible and thus finding the solution. After one too many occurences of this I think I'm going to make a big poster with this axiom on it and hang it above my monitor.
|
14
_content/Demo-of-Iterate-erlang-project-2009-4-11.yml
Normal file
14
_content/Demo-of-Iterate-erlang-project-2009-4-11.yml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
title: Demo of Iterate! erlang project number two is up
|
||||||
|
time: 2009-04-11 22:08:25
|
||||||
|
tags:
|
||||||
|
- Site-News
|
||||||
|
- erlang
|
||||||
|
- iterate
|
||||||
|
- nitrogen
|
||||||
|
content: |
|
||||||
|
Iterate*!* is my Scrum style project management tool. Inspired by my dislike
|
||||||
|
for XPlanners UI. Iterate*!* was started about a month ago and is coded in
|
||||||
|
[erlang](http://erlang.org/) using
|
||||||
|
[mochiweb](http://code.google.com/p/mochiweb/), and
|
||||||
|
[nitrogen](http://nitrogenproject.com/). Kick the tires and whatnot if you
|
||||||
|
want to see it in action: http://iterate.marzhillstudios.com:8001/
|
6
_content/Desktop-Cube-2007-2-22.yml
Normal file
6
_content/Desktop-Cube-2007-2-22.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Desktop Cube
|
||||||
|
time: 2007-02-22 16:36:50
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
Desktop Cube with 3d window effects
|
11
_content/Did-you-ever-need-to-index-an-xm-2006-5-18.yml
Normal file
11
_content/Did-you-ever-need-to-index-an-xm-2006-5-18.yml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
title: Did you ever need to index an xml doc
|
||||||
|
time: 2006-05-18 16:26:57
|
||||||
|
tags:
|
||||||
|
- Data
|
||||||
|
- Languages
|
||||||
|
- Perl
|
||||||
|
- Software-Development
|
||||||
|
- XML
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
and preserve the xml information in the index? May I present "<a href="http://jeremy.marzhillstudios.com/personal/xml_indexer.zip">the XML Indexer</a>". My brother, who's very populer <a href="http://www.walljm.com/bible/">AJAX Bible app</a> has been getting attention, needed an xml index of the KJV Bible. He asked if I could help him get it. We would be parsing the KJV in XML format and I needed to pull out the reference information for every occurence of every word. Well I thought an xml indexer might be useful in more than one capacity and there wasn't much on the net or cpan with the capability to do it. It needed to be light and fast because it was going to be parsing the entire bible so a DOM parser was out of the question. So I wrote my own. xml_indexer.pm is a module to index the words in an xml document and preserve the xml information about each occurence of the word. It's a little rough around the edges right now but it works. It uses the expat parser so it's light and fast. Look at the bible_index.pl script for an example of how it works. I'll do a tutorial on it later. <strong>Update:</strong> This baby has been confirmed to parse the entire bible in Zaphania xml format in under 3 minutes. That is a 16 MB file. It spits out a 23 MB index in that space of time. Quite honestly it surprised me.
|
6
_content/Do-people-really-believe-this-st-2005-9-28.yml
Normal file
6
_content/Do-people-really-believe-this-st-2005-9-28.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Do people really believe this stuff?
|
||||||
|
time: 2005-09-28 21:17:31
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
<a href="http://www.foxnews.com/story/0,2933,170724,00.html">FOXNews.com - Views - Massachusetts Should Close Down OpenDocument</a> Man the litany of folks not getting it just keeps growing and growing. I'm going to say this one more time. Open Source is here to stay. Get over it and start learning how to do business in the new environment. And if someone can explain how Massachusets choosing an Open Document "<em>Standard</em>" kills competition I'd like to know. I mean surely letting non microsoft providers bid on government contracts would <strong>increase</strong> not decrease competition. And no one said microsoft couldn't offer the document format themselves. Microsoft created this environment now they can sink or swim with the rest of us in it.
|
13
_content/Error-handling-Erlang-vs-Other-2009-4-11.yml
Normal file
13
_content/Error-handling-Erlang-vs-Other-2009-4-11.yml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
title: Error handling (Erlang vs Other languages)
|
||||||
|
time: 2009-04-11 09:59:12
|
||||||
|
tags:
|
||||||
|
- Site-News
|
||||||
|
- best-practices
|
||||||
|
- coding
|
||||||
|
- erlang
|
||||||
|
- functional-programming
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
When I'm in Perl, Javascript, Java, or any other programming language I prefer to throw exceptions rather than return errors. This is because I've long since gotten tired of losing errors 5 calls deep in the code because I forgot to check the return and handle it. Nothing is more annoying than trying to debug a problem that is actually caused somewhere else, but you don't know because the error vanished into the that Great Heap in the Sky around about 5 calls down. You've been there before. That's when you start adding print statements followed by an exit or, if your lucky enough to have one, firing up the debugger and using break statements to narrow down the actual source of the problem. This process could take days depending on how far removed from the breaking code the actual problem is. In erlang, however, returning errors actually turns out to be useful. This is because in erlang returning errors actually has the desired effect. Usually, when you return errors in an app, it is because you don't want to kill the whole program when something breaks. What you intend is for the caller to inspect the return and do the appropriate thing. This however runs smack into the whole <blockquote>programmers are fallible people, who sometimes stay up late coding at 3am, when they can hardly see the screen anymore</blockquote> problem. In short you are depending on the caller to honor your contract and do the right thing even though we often do exactly the wrong thing. Even when you are the caller, sometimes you don't honor that contract. Then a month later you are doing that print statement and die or perhaps the debugger dance again. All of this because of one night when your judgement lapsed. Companies will often develop elaborate style guides, testing strategy, and code-review cultures to prevent this, but in the end most developers I know come to love throwing exceptions... unless they are coding in erlang. This is because of two elements of the erlang language design: <ul> <li>Pattern Matching</li> <li>and Fail Fast.</li> </ul> In erlang returning errors <strong>requires</strong> the caller to handle them. If I try to store the return of a function and it doesn't match what I told it to expect then <strong>bang,</strong> an automatic exception. However, if I try to store the return and explicitely handle the error case then no exception is thrown. This has the wonderful effect of forcing me to think about exactly what I expect this function to return, and handling or ignoring at my choice. The big benefit is that I had to think about it. The below example illustrates the difference.
|
||||||
|
<script src="http://gist.github.com/93574.js?file=minihttpd.clj"></script>
|
||||||
|
The combination of Pattern Matching and Fail Fast in erlang forces the programmer to honor the contract, whether he wants to or not. This is one case where Erlang follows the "Do What I Need Not What I Want" principle in a language properly.
|
6
_content/Ever-wished-your-windows-box-2005-5-16.yml
Normal file
6
_content/Ever-wished-your-windows-box-2005-5-16.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Ever wished your windows box...
|
||||||
|
time: 2005-05-16 01:10:02
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
could email you when certain events happened? It has an eventlog why can't it just email when it sees an event occur? Well I decided it was time to add just that functionality. So.. . I proudly present <a href="http://jeremy.marzhillstudios.com/EventNotifier.zip">EventNotifierV2.pl</a>. A script that checks your windows eventlog for events and emails you when it sees them. Surely someone else has a need for this.
|
6
_content/Example-shortcut-2006-6-22.yml
Normal file
6
_content/Example-shortcut-2006-6-22.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Example shortcut
|
||||||
|
time: 2006-06-22 15:15:34
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
Shortcut that launches dtach and fires a shell to use in it
|
6
_content/FOAF-2006-1-25.yml
Normal file
6
_content/FOAF-2006-1-25.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: FOAF
|
||||||
|
time: 2006-01-25 14:18:04
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
<a href="http://jeremy.marzhillstudios.com/personal/foaf.rdf">I've been FOAF'ized</a> Do you have a <abbr title="Friend-Of-A-Friend">FOAF</abbr> page yet?
|
11
_content/First-Draft-of-the-Bricklayer-Do-2005-12-7.yml
Normal file
11
_content/First-Draft-of-the-Bricklayer-Do-2005-12-7.yml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
title: First Draft of the Bricklayer Documentation
|
||||||
|
time: 2005-12-07 23:44:39
|
||||||
|
tags:
|
||||||
|
- Site-News
|
||||||
|
- BrickLayer
|
||||||
|
- Languages
|
||||||
|
- Perl
|
||||||
|
- Software-Development
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
I just finished the first draft of the Bricklayer development manual. You can see it here: <a href="http://jeremy.marzhillstudios.com/bricklayer/BKManual/">Bricklayer Manual</a> Take a look and tell me if you see any thing that might need more clarification or spelling correction.
|
171
_content/First-Look-at-Polymer-Elements-2013-09-17.yaml
Executable file
171
_content/First-Look-at-Polymer-Elements-2013-09-17.yaml
Executable file
@ -0,0 +1,171 @@
|
|||||||
|
title: First Look at Polymer Elements
|
||||||
|
author: Jeremy Wall
|
||||||
|
time: 2013-09-17
|
||||||
|
timeformat: 2006-01-02
|
||||||
|
content-type: markdown
|
||||||
|
tags:
|
||||||
|
- site-news
|
||||||
|
- polymer
|
||||||
|
- web
|
||||||
|
- w3c
|
||||||
|
- webcomponents
|
||||||
|
content: |
|
||||||
|
Introduction
|
||||||
|
============
|
||||||
|
|
||||||
|
For work I've been getting up to speed on the W3C's set of webcomponents standards. Which means I've been looking at [Polymer](http://polymer-project.org). Polymer is both an experimental javascript framework and a shim library that simulates the portions of the W3C standard which are not yet implemented in browsers. Specifically I've been looking at [Custom Elements](http://www.w3.org/TR/components-intro/#custom-element-section) and [Templates](http://www.w3.org/TR/components-intro/#template-section) since they are the more concrete portions of the standard right now.
|
||||||
|
|
||||||
|
At some point when you are exploring a new technology the docs and tutorials stop being useful to you and to really get a feel you have to build something in it. I decided to port parts of a javascript application, [DynamicBible](http://dynamicbible.com), that I had already written as a learning exercise. [DynamicBible](http://dynamicbible.com) currently uses [requirejs](http://requirejs.org) for it's javascript code as a way to manage dependencies and keep scoping sane. This made it perfect for my purposes since it allowed me to explore two types of polymer elements.
|
||||||
|
|
||||||
|
* UI elements.
|
||||||
|
* Utility elements that don't have a visible presence on the page.
|
||||||
|
|
||||||
|
For my purposes I ported the DynamicBible search box and a requirejs importer element. In this article I'll cover the search box element. The requirejs element will be covered a later article.
|
||||||
|
|
||||||
|
Creating your own Polymer Element
|
||||||
|
=================================
|
||||||
|
|
||||||
|
``` html
|
||||||
|
<polymer-element name="my-element">
|
||||||
|
<template>
|
||||||
|
...
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
...
|
||||||
|
</script>
|
||||||
|
</polymer-element>
|
||||||
|
```
|
||||||
|
|
||||||
|
The `<polymer-element>` is the declarative way to define your polymer element in html itself. The bare minimum to define a polymer element would be
|
||||||
|
|
||||||
|
``` html
|
||||||
|
<polymer-element name="search-box">
|
||||||
|
<script>
|
||||||
|
Polymer('search-box');
|
||||||
|
</script>
|
||||||
|
</polymer-element>
|
||||||
|
```
|
||||||
|
|
||||||
|
This is as about as useful as the span element though and html already has a span element. We need a little more than this to be worth it. Our element needs some attributes and behavior. Polymer lets us describe the expected attributes using an attribute called, what else, `attributes`.
|
||||||
|
|
||||||
|
``` html
|
||||||
|
<polymer-element name="search-box" attributes="id query">
|
||||||
|
```
|
||||||
|
|
||||||
|
As for the behavior to attach to this element, that brings us the the Polymer construction function.
|
||||||
|
|
||||||
|
``` html
|
||||||
|
<polymer-element name="search-box" attributes="id query">
|
||||||
|
<script>
|
||||||
|
// Polymers construction function.
|
||||||
|
Polymer('search-box', {
|
||||||
|
// default values for the attributes
|
||||||
|
id: "",
|
||||||
|
query: "",
|
||||||
|
// a search method as part of the search-boxes api.
|
||||||
|
search: function() {
|
||||||
|
submitSearch(this.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</polymer-element>
|
||||||
|
```
|
||||||
|
|
||||||
|
You can use the element the same way you would any other html element.
|
||||||
|
|
||||||
|
``` html
|
||||||
|
<search-box id="searchBox"></search-box>
|
||||||
|
```
|
||||||
|
|
||||||
|
Now our element has a method on it that will submit a search using the value of our search-box query attribute. We could trigger this behavior right now with javascript.
|
||||||
|
|
||||||
|
``` js
|
||||||
|
document.querySelector('#searchBox').query = "what is a polymer element?";
|
||||||
|
document.querySelector('#searchBox').search();
|
||||||
|
```
|
||||||
|
|
||||||
|
It's kind of silly that we have to do that manually with javascript though. What we really want is for this element to detect changes in our query and perform the search for us.
|
||||||
|
|
||||||
|
``` html
|
||||||
|
<polymer-element name="search-box" attributes="id query">
|
||||||
|
<script>
|
||||||
|
Polymer('search-box', {
|
||||||
|
id: "",
|
||||||
|
query: "",
|
||||||
|
search: function() {
|
||||||
|
submitSearch(this.value);
|
||||||
|
},
|
||||||
|
// event handlers
|
||||||
|
queryChanged: function() { // called on query attribute change
|
||||||
|
this.search();
|
||||||
|
},
|
||||||
|
created: function() { // called on element creation
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</polymer-element>
|
||||||
|
```
|
||||||
|
|
||||||
|
Now when the element's query attribute changes a search is triggered.
|
||||||
|
|
||||||
|
Up to now our element hasn't been very visible. We need to give it an image boost. We can do this two different ways.
|
||||||
|
|
||||||
|
1. Using a template
|
||||||
|
2. Using element inheritance
|
||||||
|
|
||||||
|
We'll go with the template element for now. The element inheritance will come in handy later.
|
||||||
|
|
||||||
|
``` html
|
||||||
|
<polymer-element name="search-box" attributes="id query">
|
||||||
|
<template>
|
||||||
|
<input type="text" value="{{ query }}">
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
Polymer('search-box', {
|
||||||
|
id: "",
|
||||||
|
query: "",
|
||||||
|
search: function() {
|
||||||
|
submitSearch(this.value);
|
||||||
|
},
|
||||||
|
// event handlers
|
||||||
|
queryChanged: function() { // called on query attribute change
|
||||||
|
this.search();
|
||||||
|
},
|
||||||
|
created: function() { // called on element creation
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</polymer-element>
|
||||||
|
```
|
||||||
|
|
||||||
|
There are a number of things going on in this template element. First we define some html that will be used whenever we render the element on a page. There is some complicated merging logic involving the [shadow dom](http://www.w3.org/TR/components-intro/#shadow-dom-section) but we'll ignore that for now. Second our value attribute on the the input element has funny looking content. The `{{ query }}` tells polymer that the contents of the text box and the query a should be kept in sync. A change to one of them is reflected in the other. Furthermore a change to the input box will result in the queryChanged event firing and causing a search to get submitted. There are several more built in events and Polymer includes a way to create and listen to your own events. as well.
|
||||||
|
|
||||||
|
I'll cover a utility element that shims requirejs modules to make them useable in your polymer elements in a later article.
|
||||||
|
|
||||||
|
Out elements template element isn't terribly complicated and it turns out in our case is completely unnecessary. We can use `extends` to tell Polymer our element should inherit from the input element.
|
||||||
|
|
||||||
|
Our last tweak to the search-box element looks like this.
|
||||||
|
|
||||||
|
``` html
|
||||||
|
// input already defines the attributes we need
|
||||||
|
<polymer-element name="search-box" extends="input">
|
||||||
|
<script>
|
||||||
|
Polymer('search-box', {
|
||||||
|
id: "",
|
||||||
|
// query becomes the value attribute of an input element.
|
||||||
|
value: "",
|
||||||
|
search: function() {
|
||||||
|
submitSearch(this.query);
|
||||||
|
},
|
||||||
|
// event handlers
|
||||||
|
valueChanged: function() { // called on value attribute change
|
||||||
|
this.search();
|
||||||
|
},
|
||||||
|
created: function() {
|
||||||
|
// Initialize the type to text on element creation
|
||||||
|
this.type = "text"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</polymer-element>
|
||||||
|
```
|
12
_content/Functional-Programming-vs-OO-Pro-2009-4-26.yml
Normal file
12
_content/Functional-Programming-vs-OO-Pro-2009-4-26.yml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
title: Functional Programming vs OO Programming
|
||||||
|
time: 2009-04-26 20:52:39
|
||||||
|
tags:
|
||||||
|
- Site-News
|
||||||
|
- comparison
|
||||||
|
- erlang
|
||||||
|
- functional-programming
|
||||||
|
- insanity
|
||||||
|
- OO
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
I've been thinking lately about the differences between <abbr title="Object Oriented">OO</abbr> and <abbr title="Functional programming">FP</abbr>. FP languages don't really support the OO model because of a difference in design. Some try but the "true" functional languages make no such effort and for good reason. One of the primary principles of OO programming is the black box. An object is meant to represent some entity in the system. All the state and valid actions for that entity are encapsulated in the Object and the only visibility you have into them is the interface the object provides to the outside world. Programs tend to be defined as a set of interactions between objects. FP takes a different approach. In FP data is not modifiable only transformable by functions. In FP the functions expect certain input and give back certain output for that input. They certainly don't maintain any state on their own. You can't have an object if you can't have modifiable internal state. In OO you are encouraged to group together state and activity on that state. In OO you don't think so much about state as you do about entities. Person, Car, ATM machine. All of these are commonly referenced objects in an OO tutorial or textbook. Consumers of your object are encouraged not to think about the state of a person or a car or an ATM machine. Instead they think in terms of allowable interactions with that object: Talk, Drive, Withdraw Money. Within OO code there are a huge number of possible orders of various interactions possible. So large they are just about impossible to completely test or even visualize. For example say I'm programming a person object. I've given the person object a handshake method. However, depending on the internal state of the person object that method may or may not work the same way or be supposed to be called. Maybe the person object is in a bad mood, in which case the handshake method is non-functional. How do we handle that? Hrmm, so first before calling handshake on the person object we should call the offer hand method. No wait, before we call the offer hand method, perhaps we should look at their face first to gauge their mood. This could get complicated pretty quickly. Furthermore there is nothing in the OO language that allows us to specify that the offer hand method should happen first. We obviously need to know quite a bit about the state of that person object in order to properly interact with it. Contrast that with an FP approach. This gets a little bit simpler for some people to visualize suddenly. Rather than an object, they see state and a set of possible transformations of that state. the state may be something like this. person1 mood, person2 mood. and there is an interact function. If the person1 and person2 mood is good then the interact function offers hand for handshake and the two shake hands then interact returns the new person1 mood and person2 mood. Or if the mood of one of them is bad then do some other action then return new person1 mood and person 2 mood. By placing the emphasis on the state involved the coder has reduced the problem to a set of possible transformations based on that state. In OO, an object's methods define the interface. but passing the same input to an object will not always result in the same output. Most of the time methods modify internal state and the return depends on the internal state. At any time in your code the internal state of an object must be treated as an unknown. This means the return of your objects method must also be treated as an unknown. Every object has to treat every other object like it has some sort of mental disease and could have a psychotic break any moment. It could do just about anything and if you didn't define the proper response to what they do then who knows what might happen. In FP you are encouraged to think in terms of state transformations. You are forced to consider what the state you are dealing with is and then transform that state appropriately. Since the state is of primary importance after a while FP feels more natural than OO to certain mindsets. I'm discovering that I rather like the FP mindset and miss OO less and less these days. <hr /> Glossary: <dl> <dt>FP</dt> <dd>Functional Programming</dd> <dt>OO</dt> <dd>Object Oriented</dd> </dl>
|
6
_content/Gmail-*Talk-2006-2-17.yml
Normal file
6
_content/Gmail-*Talk-2006-2-17.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Gmail Talk
|
||||||
|
time: 2006-02-17 10:30:50
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
One of the things Google does well is integration that makes sense. Take the new enhancements to Gmail And Google Talk. For everyone who thought that we didn't need another talk client May I humbly present: Gmail Talk beta. I knew they had something up their sleeves. And the integration is both seamless and easy. This is what makes Web Applications done right such a beautiful thing. I just log on one day and boom my wife can IM me an important message with no work on my part whatsoever. <ul> <li>No client to install.</li> <li>No configuration option to set up. </li> <li>No service to sign into. </li> </ul> Now that is the way it should be. Invisible till I need it. Just instant communication from just about any web browser in the world. Now all I need is Google Calendar and my Google Experience is complete.
|
59
_content/Go-Html-Transform-2013-02-26-2013.yml
Normal file
59
_content/Go-Html-Transform-2013-02-26-2013.yml
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
title: go-html-transform an html transformation and scraping library
|
||||||
|
time: 2013-02-26 17:05:00
|
||||||
|
section: projects
|
||||||
|
tags:
|
||||||
|
- go
|
||||||
|
- html
|
||||||
|
- css
|
||||||
|
content: |
|
||||||
|
|
||||||
|
http://code.google.com/p/go-html-transform is my html transformation library for go. I use it as an html templating language and scraping library. It's not your typical approach to html templating but it's an approach I've really come to enjoy. HTML templating can be grouped in roughly about 3 categories.
|
||||||
|
|
||||||
|
1. Templating languages.
|
||||||
|
1. HTML DSLs.
|
||||||
|
1. Functional transforms.
|
||||||
|
|
||||||
|
go-html-transform is an example of that last one. The basic theory is that an html template is just data. No logic is in the template. All the logic is in the functions that operate on the template and any input data. Using the input data you can transfrom a template and then render the transformed AST back into html. This has a number of benefits.
|
||||||
|
|
||||||
|
* Your template transforms are context aware.
|
||||||
|
* Multipass templating is just another transform.
|
||||||
|
* All your logic is expressed in real honest to goodness code not a limited templating language. In the case of go-html-transform your templating logic is actually typechecked by the go compiler.
|
||||||
|
* It's impossible to generate bad html.
|
||||||
|
* Your mocks are your templates.
|
||||||
|
* You can use an html dsl in combination with this approach as well if the dsl outputs the same AST.
|
||||||
|
|
||||||
|
Example usage.
|
||||||
|
=======
|
||||||
|
|
||||||
|
``` go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"code.google.com/p/go-html-transform/html/transform"
|
||||||
|
"code.google.com/p/go-html-transform/h5"
|
||||||
|
)
|
||||||
|
|
||||||
|
func toSSL(url string) string {
|
||||||
|
return strings.Replace("http:", "https:", 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
f, err := os.Open("~/file.html")
|
||||||
|
defer f.Close()
|
||||||
|
if err != nil { return } // handle errors here.
|
||||||
|
tree, err := transform.NewDocFromReader(f)
|
||||||
|
if err != nil { return } // handle errors here.
|
||||||
|
t := transform.NewTransformer(tree)
|
||||||
|
t.ApplyAll(
|
||||||
|
Trans(ReplaceChildren(h5.Text("foo"), "span"), // replace every span tags contents with foo
|
||||||
|
// turn every link and img into an ssl link
|
||||||
|
Trans(TransformAttrib("href", toSSL), "a"),
|
||||||
|
Trans(TransformAttrib("src", toSSL), "img"),
|
||||||
|
)
|
||||||
|
|
||||||
|
t.Render(os.Stdout) // render html to stdout.
|
||||||
|
}
|
||||||
|
```
|
6
_content/Google-Search:-get_cookie-perl-2005-6-17.yml
Normal file
6
_content/Google-Search:-get_cookie-perl-2005-6-17.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Google Search get_cookie perl
|
||||||
|
time: 2005-06-17 03:50:56
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
Somehow my very own tutorial on perl and CGI has made it to the top of the google search heap. I don't know how long it will stay there so I thought I'd bask while I could: <a href="http://www.google.com/search?q=get_cookie+perl&sourceid=mozilla-search&start=0&start=0&ie=utf-8&oe=utf-8&client=firefox-a&rls=org.mozilla:en-US:official">Google Search: get_cookie perl</a> Guess I really do have to write part two of that thing now. I'm also on page two of a google search for "<a href="http://www.google.com/search?q=perl+cookies+keys&hl=en&hs=hoi&lr=&client=firefox-a&rls=org.mozilla:en-US:official&start=10&sa=N">perl cookies keys</a>" I found these by perusing my logs. You can find some interesting things out by looking at those
|
8
_content/Hello-2006-12-2.yml
Normal file
8
_content/Hello-2006-12-2.yml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
title: Hello!
|
||||||
|
time: 2006-12-02 19:09:34
|
||||||
|
tags:
|
||||||
|
- Site-News
|
||||||
|
- Uncategorized
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
Just Julie popping in to give a big "HI!" I thought it'd been a while since there was a post here, so here is a little one.
|
6
_content/Heres-a-gotcha-for-anyone-devel-2007-2-6.yml
Normal file
6
_content/Heres-a-gotcha-for-anyone-devel-2007-2-6.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Here's a gotcha for anyone developing with mod_perl and APR
|
||||||
|
time: 2007-02-06 01:31:29
|
||||||
|
tags: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
I had a mod perl handler that was mapped to different URL's. One worked as expected the other URL did not. Exact same code Everything was hard coded for testing so the URL had no bearing whatsoever on the code. So why on earth would one URL have an error and the other not? It took me a while but I finally figured it out. What else could have been different about the two different URL's besides the URL itself? The answer? Cookies. Specifically in this case cookies put stored by Wordpress on this particular domain. More specifically a cookie with comma's which counts as a malformed cookie and just so happens to crash Apache2::Cookie every time. Since I couldn't count on the cookie not coming back I decided to implement a workaround. So the next time you build something for the web on modperl2 using Apache2::Cookie you might just want to preprocess the Cookie header before trying to pull cookies out of it. I wrote a simple function that split the cookies out of the header removed the comma, semicolon, and any whitespace from the cookie value and then overwrote the Cookie headers before trying to retrieve the cookies. You can't always assume that the cookies you see come in are cookies you set. Cross domain cookies and Cookies used by other apps in your domain name space may be a source of trouble if you aren't careful. I learned this the hard way but at least it was on a testbed site and not something for production. Related Links: <a href="http://trac.wordpress.org/ticket/2660">Wordpress Ticket</a>
|
6
_content/I-am-now-officially-on-the-marke-2006-12-14.yml
Normal file
6
_content/I-am-now-officially-on-the-marke-2006-12-14.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: I am now officially on the market as a freelancer.
|
||||||
|
time: 2006-12-14 00:36:30
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
So contact me for a job now before I become full time employed again. For that matter feel free to contact me about full time employment too.
|
6
_content/I-changed-my-permalink-structure-2006-1-19.yml
Normal file
6
_content/I-changed-my-permalink-structure-2006-1-19.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: I changed my permalink structure
|
||||||
|
time: 2006-01-19 17:49:54
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
For two reasons. One it will make capturing a static backup of my site easier in the future using a tool like <a href="http://www.gnu.org/software/wget/wget.html">wget</a>. Two I'm using a new analytics tool and this will help me track visitor traffic in much more meaningful ways. I don't think any links you might have saved before will stop working but just in case it does... Now you know why.
|
6
_content/I-dont-usually-do-this-2006-4-5.yml
Normal file
6
_content/I-dont-usually-do-this-2006-4-5.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: I don't usually do this
|
||||||
|
time: 2006-04-05 10:54:02
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
But I have clients on Network Solutions and they must have just about the worst service I've ever seen for DNS. and to top it off their servers go down way to often for the price they charge. <a href="http://isc.sans.org/diary.php?n&storyid=1238">Case In Point</a> That was just the latest outage. So if any of you are thinking of getting DNS or Domain Names from them. Don't. Just a warning but I really haven't been impressed by them.
|
6
_content/I-upgraded-to-WP-202-finally-2006-4-18.yml
Normal file
6
_content/I-upgraded-to-WP-202-finally-2006-4-18.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: I upgraded to WP 2.0.2 finally
|
||||||
|
time: 2006-04-18 15:09:00
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
I bit the bullet and upgraded finally. And might I say the upgrade was a snap. Not a single problem while doing so. I am impressed.
|
6
_content/Im-about-to-make-your-day-2006-6-22.yml
Normal file
6
_content/Im-about-to-make-your-day-2006-6-22.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: I'm about to make your day
|
||||||
|
time: 2006-06-22 15:17:14
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
If you have always wanted the functionality of GNU Screen for your win32 box but couldn't get the win32 port to do the detach/reattach portion correctly then your not alone. And thanks to the power of open source <a href="http://dtach.sourceforge.net/">some guy created a stripped down version</a> called dtach that doesn't have all the fancy stuff. This version just so happens to compile and run perfectly on cygwin. It might even do it correctly on just a mingw32 setup. What this means is that you can now run detached terminal sessions on your windows box. I've provided the binary for you to use if you're interested. <a href="http://jeremy.marzhillstudios.com/wp-content/uploads/2006/06/dtach.exe">dtach</a> <a href="http://jeremy.marzhillstudios.com/wp-content/uploads/2006/06/dtach.lnk">Example shortcut to use it</a>
|
6
_content/Im-trying-out-a-new-theme-2005-12-8.yml
Normal file
6
_content/Im-trying-out-a-new-theme-2005-12-8.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: I'm trying out a new theme
|
||||||
|
time: 2005-12-08 22:58:34
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
I may be modifying it a bit in the next few days probably to widen it's total size since I'd like more width for the content section but I like the overall look and colors
|
9
_content/Inception:-The-Distributed-Commu-2007-1-3.yml
Normal file
9
_content/Inception:-The-Distributed-Commu-2007-1-3.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
title: Inception - The Distributed Community API
|
||||||
|
time: 2007-01-03 22:12:12
|
||||||
|
tags:
|
||||||
|
- APIs
|
||||||
|
- BrickLayer
|
||||||
|
- Software-Development
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
I have been noodling an idea lately that I think I will begin to implement in Bricklayer. A distributed MySpace/FaceBook of sorts. Think of it as everything you like about a Community Website with none of the Myspace pains. Your profile and content will be yours and under your control. But the network will still be there. It's distributed because its a network of individual unrelated sites. A Blog, Forum or Discsussion board perhaps. It will allow Disparate sites to network using similar technologies to trackback pings with less spam because a request for friend status with an identity will have to be explicitely allowed. In Theory with this API joining a community like Myspace would be as simple as requesting Friend Status with a Service Website. Leaving would be as simple as revoking the status with the Service Website. Each way you still keep the identity and Content and moving it from Service to Service or using it in Multiple Services would be simple and easy. <a href="http://spreadsheets.google.com/pub?key=p_fId9ssKcthunIHcjKl2Pw">My initial Design Notes can be found here.</a>
|
6
_content/Information-Hook-Up-2005-6-22.yml
Normal file
6
_content/Information-Hook-Up-2005-6-22.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Information "Hook-Up"
|
||||||
|
time: 2005-06-22 05:08:26
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
Are you the Information "Hook-Up" for your family and friends? Do you know the ins and outs of internet research? If someone needs something are the guy who can get it for them? Every good prison movie has the guy who can get you anything. Need a picture of Raquel Welch to hide that unsightly hole in your wall? Got a yearnin for some McDonalds food? The prison hook-up guy can get it for you. IT departments and Office area's have a similar guy. Need to find a pdf printer driver for free? I can<a href="http://sector7g.wurzel6.de/pdfcreator/index_en.htm"> get ya that</a>. Need to find information about government guidelines regarding the storage and sharing of medical data? I can <a href="http://www.hipaa.org/">get ya that</a>. Want to know the mating habits of wild geese? Yep, You guessed it. I can <a href="http://www.birdsbybent.com/ch1-10/cangoose.htm">get ya that</a>. Just call me your Information Hook-Up. Actually those aren't even obscure items. How about this one? Need to know an easy way to get at the data in STI's School Management application? Yep I <a href="http://filext.com/detaillist.php?extdetail=TPS">got</a> <a href="http://www.softvelocity.com/products/database_tsodbc.htm">that</a> too. Man... I gotta get a life.
|
6
_content/Insecurity-in-Open-Source?---A-R-2004-2-15.yml
Normal file
6
_content/Insecurity-in-Open-Source?---A-R-2004-2-15.yml
Normal file
File diff suppressed because one or more lines are too long
6
_content/Internet-Daily:-BellSouth-wants-2006-1-18.yml
Normal file
6
_content/Internet-Daily:-BellSouth-wants-2006-1-18.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Internet Daily - BellSouth wants new Net fees
|
||||||
|
time: 2006-01-18 11:33:28
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
The Net is buzzing about BellSouth and it's rather strange view on internet access. Some details can bee seen at the article below. <a href="http://www.marketwatch.com/news/archivedStory.asp?archive=true&dist=ArchiveSplash&siteid=google&guid=%7B02432D2D%2D1EE0%2D4037%2DA15F%2D54B748D6CF26%7D&returnURL=%2Fnews%2Fstory%2Easp%3Fguid%3D%7B02432D2D%2D1EE0%2D4037%2DA15F%2D54B748D6CF26%7D%26siteid%3Dgoogle%26dist%3DArchiveSplash%2C+%26archive%3Dtrue%26param%3Darchive%26garden%3D%26minisite%3D">Market Watch - BellSouth Story</a> Techdirt has had some very good commentary also: <a href="http://techdirt.com/articles/20060118/037212_F.shtml">Techdirt - BellSouth</a> It looks like someone has forgotten what exactly their product is and what the value of that product is. If you are a BellSouth customer you might do well to take a close look. An ISP sells just one thing access. And they sell it to just one market. The accessor. Google isn't using BellSouth's pipes. BellSouth's DSL customer is. The same goes for yahoo, AOL, Apple's ITunes and so on. The subscriber to the ISP requests the content. This is a PULL not a PUSH relationship. BellSouth better get it's head in the game or They are going to find they've lost their market because they forgot what product they were selling.
|
25
_content/Is-NIH-really-so-bad?-2010-3-2.yml
Normal file
25
_content/Is-NIH-really-so-bad?-2010-3-2.yml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
title: "Is NIH really so bad?"
|
||||||
|
time: 2010-03-02
|
||||||
|
timeformat: "2006-01-02"
|
||||||
|
tags:
|
||||||
|
- clojure
|
||||||
|
- molehill
|
||||||
|
- nih
|
||||||
|
- web-framework
|
||||||
|
content: |
|
||||||
|
This site is now powered using molehill. I say this because for one it's nice to announce this sort of stuff and two because it leads into the main content of the article. Molehill is a static site generator and commandline content management system. It uses vcs to track changes and can build a site from files containing content on a filesystem. Because molehill is a site generator and not a web application it doesn't serve files up as part of it's normal operation. But while developing the application I found myself wishing I could temporarily serve the content from a server to see what it looks like and behaves like in that environment. So I needed an embedded webserver. Since this wasn't meant for heavy extended use and mostly only for testing a molehill site I didn't want anything fancy or complicated to use. My requirements were simple.
|
||||||
|
|
||||||
|
1. It had to serve content from a directory
|
||||||
|
2. It had to allow you to specify the port
|
||||||
|
3. It shouldn't require a lot of dependencies
|
||||||
|
4. It shouldn't be hard to add.
|
||||||
|
|
||||||
|
Now Molehill is written in clojure, which means theoretically it has access to all the wonderful libraries java has accumulated over the years. So finding a small simple embedded webserver should be easy right? I looked at:
|
||||||
|
|
||||||
|
1. Jetty (not easy to setup or use)
|
||||||
|
2. BareHTTP (looked like it did what I needed but the code didn't actually work)
|
||||||
|
3. Commanche (not easy to setup or use)
|
||||||
|
|
||||||
|
Finally I found a less than 100 line clojure gist on github that did exactly what I needed. When I twittered about the find and my frustration looking for a java option I received responses ranging from: "Cool that didn't take long" to "Why are you so down on Jetty?" The latter opinion seemed to be that Jetty was fine so why invent another solution. One said I was crazy since his production jetty xml config file was only 50 lines long. Keep in mind that I was wanting to launch this from commandline with only a single command line parameter, the port, for configuration. I certainly didn't want to have to write an xml file every time I started a new site. Why put the user through that? Granted I could probably have programmatically configured the Jetty server using clojure code and not needed the file, but again why should I have to? In my mind the extra dependency, lack of simplicity, and general uckiness of using jetty for this wasn't a good fit. What I needed was something that fit in a single clojure file had no dependencies and did simple webserving. For that the github gist was exactly what I needed. It improved things for the user and the coder and in my mind thats a win win.
|
||||||
|
|
||||||
|
I agree that trying to invent everything yourself can be prohibitively time consuming and fraught with unexpected problems. Spending a little time looking for something that has already solved your particular problem is a good investment. But making it a religious belief can be just as prohibitive. Jetty is very good as an embeded java http servlet container and server. It does a fantastic job at this and if you need that in your app it's a lightweight way to go. But if you all you want is a temporary static site server with only two configuration options then jetty suddenly gets in your way. Sometimes the only solution is your own solution and that's ok. So the next time someone announces they had to build something because your favourite library/application/tool didn't do what they needed don't yell at them. Congratulate them on finding an unfullfilled need and wish them luck in their endeavor. It might not be NIH It might instead be NIY (Not Invented Yet) and you just didn't realize it.
|
20
_content/Learning-Erlang-2007-9-17.yml
Normal file
20
_content/Learning-Erlang-2007-9-17.yml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
title: Learning Erlang
|
||||||
|
time: 2007-09-17 03:21:21
|
||||||
|
tags:
|
||||||
|
- Site-News
|
||||||
|
- erlang
|
||||||
|
- etap
|
||||||
|
- Open-Source
|
||||||
|
- OSS-Apps
|
||||||
|
- Testing
|
||||||
|
content: |
|
||||||
|
I have taken on the task of learning erlang. I was trying to decide between
|
||||||
|
learninng Haskell, OCaml, or Erlang. OCaml, I decided against since it had too
|
||||||
|
close a similarity to C and I wanted to really stretch myself.
|
||||||
|
Haskell and Erlang both fit that bill however I found the Erlang
|
||||||
|
Documentation to be far better for someone completely new to the functional
|
||||||
|
programming world. Haskell's idea of a tutorial tried to cover too many
|
||||||
|
concepts at once and took too long to get to the hands on stuff. Also erlang
|
||||||
|
offered the opportunity to learn Distributed programming concepts along the way
|
||||||
|
so erlang it was. You can see my first erlang project
|
||||||
|
[etap here](http://github.com/zaphar/etap).
|
6
_content/Linus-speaks-out-about-DRM-GPLV3-2006-2-3.yml
Normal file
6
_content/Linus-speaks-out-about-DRM-GPLV3-2006-2-3.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Linus speaks out about DRM/GPLV3
|
||||||
|
time: 2006-02-03 11:36:11
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
If you've been floating around the net for any significant amount of time you've probably heard about <abbr title="Digital Rights Management">DRM</abbr>. And if you like Open Source you've probably heard a little about the GPLV3 license brouhaha. No doubt you're even wondering what exactly it all means. Well <a href="http://trends.newsforge.com/article.pl?sid=06/02/02/1636216">Linus sums it up pretty well</a>. The key points here are that DRM is primarily about using Valuable Security Technologies in unintended ways. The same possibilities that make DRM useful help make systems more secure. The way to Fight DRM is not fighting the technology. It's protecting the content. If you dislike DRM then make sure your content can never be used in a DRM protected work. Protect your content don't fight the technology. Open Source is winning the Software licensing battle because it produces Quality Products under a less restrictive environment for use. Open Content can do the same. That's something the EFF seems to have forgotten. Lets hope the artists start paying attention before the barrier to entry becomes too high.
|
6
_content/Look-Mom-I-Pimped-My-Desktop-2007-2-3.yml
Normal file
6
_content/Look-Mom-I-Pimped-My-Desktop-2007-2-3.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Look Mom!! I Pimped My Desktop!!!
|
||||||
|
time: 2007-02-03 01:22:16
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
Thanks to the wonders of open source. I now have a fully OpenGL Accelerated Desktop. Complete with realtime window opacity, An Expose like interface a totally awesome task switcher, wobbling windows, Window animations. But the totally blow me away feature was window thumbnailing. if I have a video running and minimize the window then hover over it in the task bar then the thumbnail shows the running video!! I'm like a kid in a candy store. Now most people would be like sure who cares but the task switcher and Expose like feature are incredibly useful. Beryl and XGL Rock!!! Screenshots to come.
|
6
_content/Looking-for-a-laptop-2007-3-23.yml
Normal file
6
_content/Looking-for-a-laptop-2007-3-23.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Looking for a laptop
|
||||||
|
time: 2007-03-23 21:40:31
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
I'm in the market for a laptop. I'm either going to be buying a refurbished Mac. Or I'm going to buy a laptop certified for linux. What I want in a laptop if I get a linux one is: already installed and configured wifi. Nvidia graphics chipset with dedicated memory at least a dvd drive dvdrw preferred at least 512mb of memor 1gb preferred at least 80 gb hdd 100 perferred 10/100 ethernet port If anyone has recommendations or even one to sell let me know. Addendum: I have purchased the laptop. I bought a sony Viao VGN AR320E.
|
6
_content/MPAAs-horror-show-Critics-not-2006-2-28.yml
Normal file
6
_content/MPAAs-horror-show-Critics-not-2006-2-28.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: MPAA's horror show. Critics not amused
|
||||||
|
time: 2006-02-28 10:30:51
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
<a href="http://lawgeek.typepad.com/lawgeek/2006/02/variety_mpaa_ca.html">Hollywood Tech group recoils in horror as Analog Hole Plug is proposed. </a> found via: <a href="http://techdirt.com/articles/20060228/0131259_F.shtml">TechDirt</a>
|
6
_content/Marzhills-new-Home-2005-4-24.yml
Normal file
6
_content/Marzhills-new-Home-2005-4-24.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Marzhill's new Home
|
||||||
|
time: 2005-04-24 08:46:38
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
As some of you noticed the site had some downtime. This occured because I was moving the server and had some problems with DNS and then Server Hardware. <em>(More on that in a moment)</em> I apologize for that if it caused you any trouble. I had been noticing a growing lack of space with my other provider, so I was looking for a different solution. It presented itself through work. My Boss actually gave me a server. Quad Pentium II processors 2 gig of Ram and 30 gigs of Raid 5 disk space. He also offered to allow me to host it off his T1. All he asked was that I set up a place for the other employees to host their own websites too. This was perfect. I had a decent server with enough space to grow into and full control over the configuration. It was like having something from ServerBeach but without the cost. I look forward to using the server as a development platform to work on some experiments in Web Application development I have had in mind for some time. I hope you will enjoy my chronicling those experiences here. Unfortunately when I got the server started I was unaware that the scsi cable had a problem. It ended up trashing the raid container and I had to rebuild. This meant that after the DNS had replicated the site was down completely since the server went down. Luckily I was able to rebuild and we are now running debian sarge with everything I need to be a webhosting provider to my coworkers, immediate family, and myself.
|
65
_content/Measuring-Developer-Skill-2015-05-09.md
Executable file
65
_content/Measuring-Developer-Skill-2015-05-09.md
Executable file
@ -0,0 +1,65 @@
|
|||||||
|
Measuring Developer Skill
|
||||||
|
=========================
|
||||||
|
|
||||||
|
A recent article about a pycon keynote by Jacob Kaplan Moss brought an
|
||||||
|
interesting question to my attention. How exactly would one measure
|
||||||
|
developer skill. It's interesting because the question itself is hard
|
||||||
|
to define properly. For one thing there are a lot of dimensions to
|
||||||
|
measure skill in. And developers hold many different roles in a team.
|
||||||
|
DevOps, Architects, Maintainers, BugFixers, Automators. Each of these
|
||||||
|
requires different skillsets. My brother who is also a developer made
|
||||||
|
the comment that skill measurements are useless without an
|
||||||
|
expectation. Against what benchmark are we measuring the skill?
|
||||||
|
|
||||||
|
I'm not at all sure there is any answer to this question that even makes
|
||||||
|
sense. But perhaps we can make some useful progress if we narrow the scope
|
||||||
|
a little.
|
||||||
|
|
||||||
|
What if we just tackled the question of API design?
|
||||||
|
|
||||||
|
Measuring a single dimension of coding skill.
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
API quality is one dimension on which you could measure developer
|
||||||
|
skill. For a measurement of API quality to be useful though it has to
|
||||||
|
be more than some elusive abstract idea of elegance or beauty
|
||||||
|
though. What would make a truly useful measurement of API quality?
|
||||||
|
|
||||||
|
When designing an API one of the commonly held goals is the principle
|
||||||
|
of least surprise. You want to build an API that makes sense to the
|
||||||
|
user and isn't bewildering in it's behavior. This seems like it
|
||||||
|
should somehow be measurable right? But how do you measure how
|
||||||
|
"surprising" an api is?
|
||||||
|
|
||||||
|
Another commonly held goal is the to reduce complexity. An API's
|
||||||
|
purpose is to hide a lot of the complexity in a problem and make it
|
||||||
|
comprehensible to the user.
|
||||||
|
|
||||||
|
Both of these ideas at there core are centered around the concept of ease of use.
|
||||||
|
What we need is a way of quantifying Ease of Use in a measurable form.
|
||||||
|
|
||||||
|
# WTF/dev/day #
|
||||||
|
|
||||||
|
Really the reason we care about ease of use is because it reduces
|
||||||
|
frustration when we consume an API. So the *number* we are trying to
|
||||||
|
reduce is the count of WTF's devs encounter when working with an
|
||||||
|
API. We could simply measure how many times a developer encounters a
|
||||||
|
WTF when using an API. But this is of course inherently biased. We
|
||||||
|
need a way to control or reduce that bias if we care about creating a
|
||||||
|
measurement that is useful to an industry.
|
||||||
|
|
||||||
|
What factors do we need to control for in a measurement of coding skill?
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Assuming we are measuring in a single dimension we are going to have to decide
|
||||||
|
exactly what factors are important and what factors should be controlled for in
|
||||||
|
our measurements.
|
||||||
|
|
||||||
|
People with stockholm syndrome are obviously going to experience less
|
||||||
|
wtf's per day than someone new to an API. The quality of the API's
|
||||||
|
documentation also affects the wtf count. Which brings up a
|
||||||
|
question. Is the documenation a part of the API? should it be a
|
||||||
|
factor in our measurement or should it be restricted to code alone?
|
||||||
|
|
||||||
|
We will encounter hundreds of these factors for any dimension we
|
||||||
|
attempt to measure. Collecting useful data here is a hard problem.
|
10
_content/Measuring-Developer-Skill-2015-05-09.yaml
Executable file
10
_content/Measuring-Developer-Skill-2015-05-09.yaml
Executable file
@ -0,0 +1,10 @@
|
|||||||
|
title: Measuring Developer Skill
|
||||||
|
author: Jeremy Wall
|
||||||
|
time: 2015-05-09
|
||||||
|
timeformat: 2006-01-02
|
||||||
|
content-type: markdown
|
||||||
|
tags:
|
||||||
|
- measurement
|
||||||
|
- skill
|
||||||
|
- developers
|
||||||
|
- hiring
|
6
_content/MetaBase-2006-4-3.yml
Normal file
6
_content/MetaBase-2006-4-3.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: MetaBase
|
||||||
|
time: 2006-04-03 21:40:04
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
Have you ever wished your CMS seamlessly handled multiple types of content and multiple ways of organizing, storing, and presenting them? Well so have I. So now after 2 years of working on Bricklayer off and on I'm finally going to build something useful with it. I'm a man with many interests and I'd like to store and share them all. MetaBase will be designed with that in mind. Whether it's an image, essay, diary entry, or tutorial or howto, MetaBase will handle it and display it in an appropriate way. It will also allow me to manage it using such exciting technologies as metadata, tagging, and hiearchical ranking. This should be fun.
|
8
_content/MetaData-and-Database-design-2005-9-27.yml
Normal file
8
_content/MetaData-and-Database-design-2005-9-27.yml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
title: MetaData and Database design
|
||||||
|
time: 2005-09-27 00:36:36
|
||||||
|
tags:
|
||||||
|
- Data
|
||||||
|
- Software-Development
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
Recognizing the difference between your Data and your Metadata can go a long way toward keeping your data formats extensible. Theoretically keeping your data generic and using metadata to describe it can allow for much greater flexibility in your application's design. Planning for, and accounting for, the ability to add more metadata on the fly can allow you a much greater capacity for growth in the types of data your application can handle. I'm experiencing this in a current project in fact. The company in question is growing and is faced with a need to change their current application to allow for that growth. A massive refactoring of the application is going to be needed. They will have to be able to add new "products" (otherwise known as data) to the application and present more ways for customers to get access to said product. A metadata based design in their data format will give them that kind of flexibility.
|
13
_content/Mnesia-and-Schema-upgrades-2009-4-16.yml
Normal file
13
_content/Mnesia-and-Schema-upgrades-2009-4-16.yml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
title: Mnesia and Schema upgrades.
|
||||||
|
time: 2009-04-16 19:41:41
|
||||||
|
tags:
|
||||||
|
- Site-News
|
||||||
|
- databases
|
||||||
|
- erlang
|
||||||
|
- mnesia
|
||||||
|
- upgrades
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
I had an epiphany or sorts the other day. While working on iterate I realized that I was going to need to upgrade the schema of my mnesia tables. Schema changes on databases often mean bringing down the application. At least they usually have in my experience anyway. I hate to upgrade databases. That is I did until I met erlang and mnesia. The issue is that my mnesia schema for some tables was using a user provided name for the primary key. This was fine while it was just a prototype but now it was time for it to grow up. The record describing the table had to change and all the records in a table had to change. Now no one is really using this right now so I had a choice. <ul> <li>Blow away the database and rebuild it.</li> <li>Be all erlang'y and stuff and do it live.</li> </ul> Wait a minute did he just say "live"? You can't update the schema and convert all the records live. That's crazy! Ahhh but this is erlang we do things different here. Witness the glory of iterate's db_migrate_tools:
|
||||||
|
<script src="http://gist.github.com/96772.js?file=minihttpd.clj"></script>
|
||||||
|
Notice, the transform_stories function. It defines an anonymous fun it uses to transform the mnesia table with. Currently this function only has one signature. There is no reason it can't have more thoug. Since, erlang allows multiple signatures for anonymous functions, I can specify a signature for the next version of the mnesia table if/when it changes again. Here's the epiphany part. I can keep updating that fun with more signatures for each version of the table. Theoretically ,if I were to end up with a table that had records of multiple different historical types in it, I would be able to use this one transform function to get them all updated to the new record type. And I can do this all live without taking down the database or app. I can ship each iterate version with a module capable of updating the database live from any previous version. Now that's power that's useful. Try doing that with another platform.
|
6
_content/Mod_Perl-20---A-Real-World-Guid-2006-4-22.yml
Normal file
6
_content/Mod_Perl-20---A-Real-World-Guid-2006-4-22.yml
Normal file
File diff suppressed because one or more lines are too long
9
_content/Mod_Perl-20---First-in-a-series-2006-4-22.yml
Normal file
9
_content/Mod_Perl-20---First-in-a-series-2006-4-22.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
title: Mod_Perl 2.0 - First in a series
|
||||||
|
time: 2006-04-22 20:40:00
|
||||||
|
tags:
|
||||||
|
- APIs
|
||||||
|
- Perl
|
||||||
|
- Software-Development
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
I have put up a <a href="http://jeremy.marzhillstudios.com/index.php/mod_perl-20/mod_perl-20-a-real-world-guide-part-i/">new page on mod_perl development</a> on the site. I hope it is of use to someone. If it isn't well at least I still have my own notes :-) You can find it here: <a href="http://jeremy.marzhillstudios.com/index.php/mod_perl-20/mod_perl-20-a-real-world-guide-part-i/">Mod_Perl 2.0 - A Real World Guide - part I</a>
|
6
_content/Mod_Perl-20---Second-in-a-serie-2006-5-11.yml
Normal file
6
_content/Mod_Perl-20---Second-in-a-serie-2006-5-11.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Mod_Perl 2.0 - Second in a series
|
||||||
|
time: 2006-05-11 11:24:43
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
My next mod_perl article is up: <a href="http://jeremy.marzhillstudios.com/index.php/mod_perl-20/mod_perl-20-writing-a-useful-handler/">Mod_Perl 2.0 Writing a Useful Handler</a> Read it while it's hot.
|
6
_content/Mod_Perl-20---writing-a-useful-2006-5-11.yml
Normal file
6
_content/Mod_Perl-20---writing-a-useful-2006-5-11.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Mod_Perl 2.0 - writing a useful handler
|
||||||
|
time: 2006-05-11 11:15:09
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
In the last article we looked at all the tools mod_perl gives us when using it. Now lets take a look at some of the things you can do with those tools. I will be demonstrating what use those tools can be in a real world app. The first thing to do is create our skeleton handler for the app. You can use the handler we put together in the previous article for this. Just replace the contents of the handler subroutine with the code we will be generating here. I'm using my <a href="http://jeremy.marzhillstudios.com/bricklayer/BKManual/">bricklayer framework</a> to demonstrate this but the lessons apply equally well to most other applications. The first thing we need to do is load any libraries we might need. In my case this is just the bricklayer module. <blockquote><code> package mod_perl_wrapper; use strict; use warnings FATAL => 'all'; no warnings 'redefine'; use lib "/data/Jeremy/workspace/BrickLayer_Main"; #Apache2 Mod_Perl2 libraries use Apache2::RequestRec (); use Apache2::RequestIO (); use Apache2::Filter (); use Apache2::Const -compile => qw(DECLINED OK); #the apache2 constants we need # Bricklayer Library use BrickLayer (); #my bricklayer module sub handler { } 1; </code></blockquote> There a several things to note about the code above. First is the use lib. mod_perl looks in the usual places for your libraries. You might think that just a simple . in the @INC array will make it look in the same location as your handler. However in a mod_perl environment ./ actually refers to the Apache root directory. Therefore it's always a good idea to explicitely tell it any nonstandard library locations in your handler. Also note the mod_perl2 libraries I loaded. These are the most common libraries your app will need so I included them here. Now lets get started building that app shall we? Our handler has several jobs to do. <ol> <li>examine the URL string to see what page was requested</li> <li>examine and request variables and modify them appropriately</li> <li>retrieve any post information and send that to the appliaction or provide a way for that application to retrieve it</li> <li>run the application</li> </ol> To this end we need to know the path_info(), the args(), the contents of read() and be able to pass that information to our application. So lets take a look at accomplishing those tasks now. First we need to see what page was requested. We can get this information from the path_info method of our Apache2::RequestRec object. Once we have retrieved it we can parse out the needed information. In my case I want to look for *.txml files and turn those into a page request in the request string. This will allow me to hit my template files directly without anyone knowing or caring if I use a perl script to parse them first. It makes my URL's friendlier and helps in site tracking. To that end I need to take any .txml files requested and prepend or append them to my request string. Here is an example of just that. <blockquote><code> #$_[0] is our Apache2::RequestRec object my $pathinfo = ""; $pathinfo .= $_[0]->path_info(); return Apache2::Const::DECLINED unless ($pathinfo =~ m/(\.txml$)|(\/$)/g) or ($pathinfo eq ""); $pathinfo =~ s/^\///; $pathinfo =~ s/\//::/; $pathinfo =~ s/.txml//; #rewrite the request string; $_[0]->args("Page=$pathinfo\&".$_[0]->args()) unless $pathinfo eq ""; # </code></blockquote> First we retrieve the pathinfo string and test to make sure it contains a *.txml file at the end. We don't care for this example if there are any at the beginning so we will consider anything else to invalid for us to handle. If there is no .txml at the end then we decline to handle this request and let apache take over. by returning the Apache2::Const::DECLINED constant. If there was a *.txml file requested though then we want to capture that and modify it for use in the bricklayer app. I use a series of substitution expressions to rewrite the path string stripping off the beginning slash and changing all other slashes to "::" so that bricklayer can understand the template request. Once I have rewritten the string I prepend it to the argument list as a Page argument using the args() method. This method both retrieves and lets us set the argument string. One nifty thing about mod_perl environments is that you can freely choose to ignore whether or not you are processing a POST or GET request. This means you can post a form to a request string and still retrieve the request string variables. Something that would have been difficult to do in traditional CGI environment. It also means that when I translate this path request I don't have to worry about whether this was GET or POST request since my cgi wrapper can process both simultaneously. That's really all my handler needs to do now it just calls the bricklayer app and runs it with the new request string. We aren't finished yet though. The next article will cover how I created a CGI wrapper and rewrote CGI_Lite.pm to handle mod_perl requests.
|
6
_content/Mod_Perl-20-2006-4-22.yml
Normal file
6
_content/Mod_Perl-20-2006-4-22.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Mod_Perl 2.0
|
||||||
|
time: 2006-04-22 20:33:50
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
Here is my collection of Mod_Perl 2.0 tutorials and notes. <ul> <li><a href="http://jeremy.marzhillstudios.com/index.php/mod_perl-20/mod_perl-20-a-real-world-guide-part-i/">Mod_Perl 2.0 - A Real World Guide - part I</a></li> <li><a href="http://jeremy.marzhillstudios.com/index.php/mod_perl-20/mod_perl-20-writing-a-useful-handler/">Mod_Perl 2.0 - writing a useful handler</a></li> </ul>
|
6
_content/Moose::Role-Testing-2007-9-22.yml
Normal file
6
_content/Moose::Role-Testing-2007-9-22.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: "Moose::Role Testing"
|
||||||
|
time: 2007-09-22 05:28:23
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
Currently there is no simple way to test Moose::Roles. Since they defer things like attribute adding and method wrapping you have to create a dummy class that uses them to test what they do. Usually this is through creating a package inline in the test module that does what you need or don't need based on what your testing. Therefore I'm considering either adding Role support to Test::Moose or creating a Test::Moose::MockObject module to make this easier. Still trying to decide which way to go. Maybe I'll go both ways :-)
|
6
_content/More-Beryl-XGL-goodness:-Tabbing-2007-2-13.yml
Normal file
6
_content/More-Beryl-XGL-goodness:-Tabbing-2007-2-13.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: More Beryl/XGL goodness Tabbing
|
||||||
|
time: 2007-02-13 12:48:52
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
Beryl has a feature called Grouping and Tabbing. It's a way to organize windows on your desktop to save space. And as promised I have screenshots demonstrating the feature. This first one shows the tabbed group with the tab selection popup. <a class="imagelink" href="http://jeremy.marzhillstudios.com/wp-content/uploads/2007/02/TabbedWindowsBig.png" title="BerylTabbing"><img id="image115" src="http://jeremy.marzhillstudios.com/wp-content/uploads/2007/02/TabbedWindowsBig.thumbnail.png" alt="BerylTabbing" /></a> You can choose your animation when switching tabs just like anything else in Beryl. Here is a screenshot of the rotation animation when switching tabs. <a class="imagelink" href="http://jeremy.marzhillstudios.com/wp-content/uploads/2007/02/SwitchingTabsBig.png" title="Switching Tabs in a Tabbed Group"><img id="image116" src="http://jeremy.marzhillstudios.com/wp-content/uploads/2007/02/SwitchingTabsBig.thumbnail.png" alt="Switching Tabs in a Tabbed Group" /></a> Stay tuned for more screenshots as I identify features that I think are worth highlighting. Next will be some transparency examples and window thumbnailing.
|
6
_content/Moving-2006-6-3.yml
Normal file
6
_content/Moving-2006-6-3.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Moving
|
||||||
|
time: 2006-06-03 18:57:21
|
||||||
|
section: Uncategorized
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
Moving makes me a little on edge like a cat. I feel like I'm flying around like a fledgling lost in a sea of boxes. I'll go batty if we don't clear out our dining room soon. (That's where all the boxes are kept.) <a href="http://julie.marzhillstudios.com/index.php/general/critter-corner/">Confused?</a> <strong>Ack, my blog has been hijacked!</strong> HA HA!!! don't worry folks it's just my wife playing a joke on me. :-)
|
9
_content/New-Article:-Non-Discriminatory-2005-10-7.yml
Normal file
9
_content/New-Article:-Non-Discriminatory-2005-10-7.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
title: Non-Discriminatory Databases
|
||||||
|
time: 2005-10-07 00:35:57
|
||||||
|
tags:
|
||||||
|
- Site-News
|
||||||
|
- Data
|
||||||
|
- Software-Development
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
<a href="http://jeremy.marzhillstudios.com/?page_id=37">Non-Discriminatory Databases</a> An article about MetaData and Database Design. Mostly just a look inside my thoughts recently on Database design and on the fly expandability.
|
6
_content/New-Link-Spam?-2005-9-8.yml
Normal file
6
_content/New-Link-Spam?-2005-9-8.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: New Link Spam?
|
||||||
|
time: 2005-09-08 20:32:42
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
Has anyone noticed spurious referrer's showing up in your website logs? I have noticed strange referrer's showing up. It's looking like they were using bogus referrals to get their link on my log page to bump their google rating. I've now removed my logs link from the sidebar and added /logs/ to the robots.txt file so it won't benefit them anymore. But it was still annoying. Has anyone else noticed this kind of thing before?
|
6
_content/Non-Discriminatory-Databases-2005-9-28.yml
Normal file
6
_content/Non-Discriminatory-Databases-2005-9-28.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Non-Discriminatory Databases
|
||||||
|
time: 2005-09-28 19:56:44
|
||||||
|
section: Uncategorized
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
Most databases these days are RDBMS types. An RDBMS is all about identifying linkages between Pieces of Data. Usually using a unique identifier known as a primary key. They can often get to be really big with lots of interconnections in the various tables. They also have one important feature. They may tend to force you to make assumptions about the data. You are retrieving. A Table expects certain kinds of data in certain kinds of formats. If you need to add a kind of data you have to either create a new table with new linkages or you have to modify the table in question. Either one means more work for you. If your database is too discriminatory it might even be impossible without massive rewriting of your code. This is great if you want to limit and enforce data relationships. But what if you want freeform relationships. What if you want to be able to modify and change the way your data relates on the fly? What if you app needs non-discriminatory data types? An RDBMS may not be the way to go. A sufficiently complex Database with lots of data relationships can be impossible to modify at times. You might be faced with a choice, add a new set of tables and relationships (thus contributing to the growing complexity and the problem) or create a whole new database and export, then import your data into the new database with any translating you might need along the way. Metadata to the rescue!!! All pieces of information have metadata associated. Simply put, Metadata describes a piece of information. A checking accounts balance might have the following associated Metadata: It's an integer, It's currency, It's rounded off to two decimal points when displayed, It's referring to account 55341 at bank of somewheresville, you wish it were a higher number. All of this Metadata puts the number into context for you. In fact that is the other way of describing metadata, (The context your information inhabits.) For some applications, information context is the name of the game. Those applications can benefit from a Metadata based information design. Storing your music collection, for instance, is one such application. You choose what music to listen too based off of your mood. Maybe you want something soothing, so you choose soothing classical music. Soothing and classical are metadata about the song title. If you music database allows for on the fly metadata about the song titles then classifying and finding your music is potentially much easier. At it's most basic a Metadata based database design is extremely simple in structure. All that is required is two "tables". One "table" only needs two columns. An indentifier and a peice of information. The other one needs needs three columns: metadata type column, an information link, and the metadata content. <img src='/personal/MetaDataDB.png' alt='MetaData Design Graph' /> The real power of this is what it allows you to do in your code. Adding Metadata is dead simple. You can organize and sort you data in any fashion you want to. You can update, change, or expand your data description on the fly with changes to the database. A whole world of possibilities begins to expand before you. Not every application can benefit from that kind of flexibility though. Certain Applications need the strict control over relationships that a traditional RDBMS design gives. Accounting applications for instance rely on strictly defined relationships. But if your application can benefit from this then it's a huge boon to your development and design to use.
|
7
_content/OK-so-I-was-a-little-over-the-to-2006-1-2.yml
Normal file
7
_content/OK-so-I-was-a-little-over-the-to-2006-1-2.yml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
title: OK so I was a little over the top with that last one
|
||||||
|
time: 2006-01-02 11:15:32
|
||||||
|
tags:
|
||||||
|
- Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
You'll have to forgive me. IIS and it's quirks just caught me at a bad time. I guess I should retract my call for murder. It's not Microsoft's fault they designed it badly. Well ok maybe it is but that's no reason to kill the programmer.... Is It??
|
9
_content/OSS-Roundup-Series---I-trust-Ope-2005-10-26.yml
Normal file
9
_content/OSS-Roundup-Series---I-trust-Ope-2005-10-26.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
title: OSS Roundup Series - I trust Open Source
|
||||||
|
time: 2005-10-26 00:14:19
|
||||||
|
tags:
|
||||||
|
- Site-News
|
||||||
|
- Open-Source
|
||||||
|
- OSS-Apps
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
I'm planning to write a series of articles on Open Source Tools and Applications that I feel are ready for prime time desktop useage. I'll write one article for each app and list their relative strengths and weaknesses. If any of you read my stuff for any period of time you'll know I tend to use a lot of Open Source Software. This is for several reasons: <ol> <li>I can't afford to buy commercial stuff</li> <li>Open Source is one way I am a good steward</li> <li>I trust Open Source Software</li> </ol> <strong>I can't afford to buy commercial</strong> I mean really. I have 5 kids, I'm technically below the poverty level, and I need a working decent computer with software to do my job. How am I supposed to shell out 300+ dollars for an operating system, 399 dollars for a low end office suite, 109 dollars for the lowest end development environment, and we haven't even touched the ancillary stuff I'd need. Furthermore I'm supposed to shell that out every couple years? I'm sorry that just won't cut it. If I had to do that I'd have to get out this business altogether. <strong>Open Source is one way I am a good steward</strong> This relates to the above. I'm a christian so I believe God holds me accountable to how I spend my money. Hardware leaves me little choice. I don't buy top of the line but I do have to buy it. That comes out to a couple hundred here, a couple hundred there. Software is the only place I have an opportunity to cut spending. And I only have that opportunity because of Open Source. Where else can I get an entire operating system, plus a development environment, plus an office suite, plus a whole host of ancillary apps to help me do my job for the low low price of 80 dollars in a boxed set, or 0 if I have an internet broadband connection? Certainly not in Closed Source Software. <strong>I trust Open Source Software</strong> We've all seen some of the fear being spread around about open source software. It's volunteer driven, it must be lower quality. It's a free for all, anyone might put a security hole in there. You don't have any protection if stuff goes wrong. Who do you turn to when you need help. Let me just say. I've dealt with my share of Commercial Software companies. I've had to wait on the line for tech support. I've used the commercial offerings. They all had bugs. They all people with no clue taking tech support calls. In short it's no better on the Commercial Side than it is on the Open Source. It's a level playing field. At least, if your using open source, someone like me doesn't shudder when you ask if we can help fix your computer. We might even enjoy doing it. More and more software companies are putting out software that phones home. Right now it's optional. Soon it won't be. I have no control over what information is collected about me. So what? you might say. I don't have anything to hide. Well just think about the amount of spam you get. Now multiply that by a large number and imagine your spam filters trying to cope. Outlook Express? It's toast baby. It's not just about having something to hide. Can you trust that company to keep the information safe? Maybe the company has no nefarious plans for it but what about the employees? Or that clever hacker who just found a way in. Can that company keep your information safe from prying eyes? In my line of work I read every day about some major company that had somehow leaked personal information about it's customers. Lives were destroyed, Credit Ratings went down the tubes. I'm sorry but the less people who have copies of my Info the better. I can be sure that mainstream Open Source software doesn't phone home. Because if it did, Someone out there would have blown the whistle. <strong>I</strong> would have blown the whistle. On the whole us OSS types are pretty sharp about that stuff. So in short, I <em>Trust</em> Open Source.
|
15
_content/Oh-my-goodness-he-just-updated-h-2009-4-5.yml
Normal file
15
_content/Oh-my-goodness-he-just-updated-h-2009-4-5.yml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
title: Oh my goodness he just updated his blog!!
|
||||||
|
time: 2009-04-05 20:29:18
|
||||||
|
tags:
|
||||||
|
- Site-News
|
||||||
|
- javascript
|
||||||
|
- etap
|
||||||
|
- google
|
||||||
|
- javascript
|
||||||
|
- joose
|
||||||
|
- life
|
||||||
|
- updates
|
||||||
|
- whirlwind
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
Hi there! Honestly I'm not dead, I've just been all wrapped up in this whole life thing. You know... that whole, "Holy cow!!!! I work at Google now!! When did this happen exactly?" thing, where you're incredibly busy just trying to get up to speed on it all and catch your breath? Well anyway, I feel bad since I've been silent for so long, so here goes. An update from the trenches of the Life of Jeremy Wall. Since I wrote last I have <ul> <li> been "acquired by Google"</li> <li> had my first "truly successful" Open Source Project</li> <li> and actually got my Student Loan back under control.</li> </ul> I'm actually absurdly proud of that last one... And still a bit bewildered by the first one. So lets go down the list one at a time shall we? <h2>"The Acquisition"</h2> The company I worked for DoubleClick Performics got bought by Google. Who would have thought it? Somehow I landed an actual job at Google doing what I love. Crafting Code. I have to say, I think this has to have been a "God thing". I can't see any other way to explain it. Google of course is an awesome place to work. Free food, Smart people, Gameroom (strangely I almost never make into there though), Snacks, and really interesting technology to play with. I'm learning a lot about working in Highly Available, Highly Scalable environments. I keep waiting to wake up and find out it was all a dream. <h2>"The Open Source Project"</h2> My last post was about etap, my learn erlang project. I had no idea that the project would get the attention of Nick, a coder with EA, who was looking for a TAP compliant testing framework for their erlang code. He contacted me and asked if he could take over management of the code. I said" sure", as long as I still got to contribute when I had time. Before I knew it EA was using etap internally and I had what I consider to be my first truly successful open source project. etap has now gotten used commercially, traveled to conferences, and is soon to be featured in a book. Not bad for a learners project huh? <h2>"The School Loan"</h2> And perhaps most awesome of all I'm making headway on the whole credit repair thing. The school loan is back under control and no longer has a devestating impact on my credit report. This is an accomplishment that makes me really wonder if I'm in some kind of awesome dream or something. Life is really looking up around here. I'll try to get more regular on my posting again as I play with more erlang, think about writing a book, and Oh almost forgot to mention "Joose" the meta-object protocol for javascript. I'll write more about that later.
|
11
_content/Old-Article-Back-up-2005-5-4.yml
Normal file
11
_content/Old-Article-Back-up-2005-5-4.yml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
title: Old Article Back up
|
||||||
|
time: 2005-05-04 01:30:17
|
||||||
|
tags:
|
||||||
|
- Site-News
|
||||||
|
- Data
|
||||||
|
- Perl
|
||||||
|
- Software-Development
|
||||||
|
- XML
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
I am slowly getting some of my old article's back up and online. You will start to see them in the links under pages on the sidebar. As I determine they are useful or helpful I will put them back up. The first is <a href="http://jeremy.marzhillstudios.com/?page_id=8">Perl and CGI part I</a> I really should do part II of that one I suppose :-)
|
17
_content/On-Inertia-2014-05-21.yml
Executable file
17
_content/On-Inertia-2014-05-21.yml
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
title: On Inertia
|
||||||
|
author: Jeremy Wall
|
||||||
|
time: 2014-05-21
|
||||||
|
timeformat: 2006-01-02
|
||||||
|
content-type: markdown
|
||||||
|
tags:
|
||||||
|
- site-news
|
||||||
|
- job-change
|
||||||
|
content: |
|
||||||
|
This is my last week at Google.
|
||||||
|
===============================
|
||||||
|
|
||||||
|
Friday will be my last day. Which feels very strange I must admit. I'm a high inertia person. I tend to stay the course once I've picked one which is probably why I've been at Google for 6 years now. But now that is all changing so this is as a good a time as any to look back.
|
||||||
|
|
||||||
|
Google is without a doubt the best company I've worked for to date. It's a deeply engineering centric company which has many benefits. They invest heavily in engineering tooling and engineering culture. Everything from build tools to source control has had significant resources poured into them at Google and it shows.
|
||||||
|
|
||||||
|
But by far the best feature of Google as a company has nothing to do with the engineering culture. Googles best feature is it's conscience. Without a doubt Google is the most moral company I have ever worked for. It's the kind of thing that is hard to verify from the outside but from the inside it's obvious that Google has a significant conscience in it's employees and it listens to that conscience and changes course as a result.
|
86
_content/On-the-fly-Perl-Classes-with-Typ-2007-1-25.yml
Normal file
86
_content/On-the-fly-Perl-Classes-with-Typ-2007-1-25.yml
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
title: On the fly Perl Classes with Type restricted attributes
|
||||||
|
time: 2007-01-25 19:34:17
|
||||||
|
tags:
|
||||||
|
- Site-News
|
||||||
|
- Perl
|
||||||
|
- Software-Development
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
There is a CPAN module <a href="http://search.cpan.org/~nwclark/perl-5.8.8/lib/Class/Struct.pm">Class::Struct</a> that can give you this same functionality. But fool that I am I like to do things the hard way. Now the differences in the useage of this implementation, while it may not do things as automatically as Class Struct does, will allow you to create simple type restricted attributes on the fly in your code with a simple one line class method. You could even bundle this in with an AUTOLOAD function to build the attributes as you need them. Also the class attributes are added at runtime and with a little extra work you can even specify such things as typed arrays or hashes. Ok enough Pro's and Cons lets take a look at the code. First we take a look at our base class that does most of the work. <code syntax=perl>
|
||||||
|
package Class::Builder;
|
||||||
|
sub new {
|
||||||
|
my $class = ref($_[0]) || $_[0];
|
||||||
|
my $self = {};
|
||||||
|
return bless($self, $class);
|
||||||
|
}
|
||||||
|
sub attribute {
|
||||||
|
my $self = $_[0];
|
||||||
|
my $type = $_[1];
|
||||||
|
my $attribute = $_[2];
|
||||||
|
my $value = $_[3];
|
||||||
|
if ($value) {
|
||||||
|
#handle INT case
|
||||||
|
if ($type eq "INT") {
|
||||||
|
if ($value =~ /^[0-9]+$/) {
|
||||||
|
$_[0]->{$attribute} = $_[3];
|
||||||
|
return $_[0]->{$attribute};
|
||||||
|
} else {
|
||||||
|
$_[0]->err("Not a $type value for $attribute");
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
} elsif ($type eq "SCALAR") {
|
||||||
|
#handle simple SCALAR case $_[0]->{$attribute} = $_[3];
|
||||||
|
return $_[0]->{$attribute};
|
||||||
|
} elsif (ref($value) eq $type) {
|
||||||
|
#handle other types
|
||||||
|
$_[0]->{$attribute} = $_[3];
|
||||||
|
return $_[0]->{$attribute};
|
||||||
|
} else {
|
||||||
|
$_[0]->err("Not a $type value for $attribute");
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$_[0]->err("No value passed for $attribute in ".ref($_[0]));
|
||||||
|
}
|
||||||
|
return $_[0]->{$attribute};
|
||||||
|
}
|
||||||
|
sub err {
|
||||||
|
$_[0]->{err} = $_[1] if $_[1];
|
||||||
|
return $_[0]->{err};
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
</code> Now lets see how we can use it. <code syntax=perl>
|
||||||
|
package Document;
|
||||||
|
use Class::Builder;
|
||||||
|
use Document::Section;
|
||||||
|
use base qw(Class::Builder);
|
||||||
|
#Attribute Methods
|
||||||
|
# example of a SCALAR Typed Attribute implementation
|
||||||
|
sub Name {
|
||||||
|
return $_[0]->attribute('SCALAR', 'Name', $_[1]);
|
||||||
|
}
|
||||||
|
#Example of a ARRAY Typed Attribute with a further simple check
|
||||||
|
#that the array elements are of type: Document::Section
|
||||||
|
sub Sections {
|
||||||
|
my $arraytype = 'Document::Section';
|
||||||
|
my $sections_old = $_[0]->Sections();
|
||||||
|
my $sections = $_[0]->attribute('ARRAY', 'Sections', $_[1]);
|
||||||
|
foreach (@$_[0]) {
|
||||||
|
if (ref($_) ne $arraytype) { #throw an error here
|
||||||
|
$_[0]->err("Invalid Array Element $arraytype");
|
||||||
|
$_[0]->attribute('ARRAY', 'Sections', $sections_old);
|
||||||
|
# reset the Sections array return undef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# die "sections is a ".ref($sections);
|
||||||
|
return $sections;
|
||||||
|
}
|
||||||
|
# example of a HASH typed Attribute
|
||||||
|
sub Meta {
|
||||||
|
return $_[0]->attribute('HASH', 'Meta', $_[1]);
|
||||||
|
}
|
||||||
|
# example of an INT typed Attribute;
|
||||||
|
sub Cursor {
|
||||||
|
return $_[0]->attribute('INT', 'Cursor', $_[1]);
|
||||||
|
}
|
||||||
|
</code> I'm not finished modifying this concept so I may post some additional enhancments later. But you can get the idea now.
|
7
_content/Open-Letter-to-Sony-Music-2005-11-1.yml
Normal file
7
_content/Open-Letter-to-Sony-Music-2005-11-1.yml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
title: Open Letter to Sony Music
|
||||||
|
time: 2005-11-01 22:35:41
|
||||||
|
tags:
|
||||||
|
- Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
I recently wrote to Sony Music regarding their controversial DRM Technology. Below is the text of the message. Some of you may have heard of the "RootKit" controversy surrounding Sony's DRM protectes Music CD's. I recently wrote about how I trusted Open Source Technology. This is one more example of why that is. You don't always know what a Closed Source company is doing with their Software and the consequences can be disasterous. Here is the text of my message to Sony Music: <blockquote>To Whom It May Concern I have recently been made aware of some disturbing facts regarding your DRM Technology for music. While I appreciate your desire to protect your investment in music labels and artists I must strongly disagree with your decision to unknowingly install "rootkit" based technology on computers that have these CD's inserted into them. I work for a company that manages networks totalling over 7000+ computers. I am now forced to advise our customers that putting sony music cd's into machines on their networks is strongly discouraged as a matter of policy. I can't take the chance that the number of security holes your DRM Software introduces will help to take down one of our networks. I regret to inform you of this but I hope that you will give it due consideration and consider altering your policy and paying closer attention to the ramifications of the DRM technology you employ. Jeremy Wall Quality Network Solutions jwall@qnsk12.com </blockquote> <strong>Addendum:</strong> For those of you who don't know a rootkit is an application that embeds itself into your operating system at a very deep level and allows the creator to control your computer without your knowledge. It is often employed by a hackers to remain undetected once they are on your system. Sony's use of the technology is highly irresponsible.
|
9
_content/OpenOfficeorg-||-A-real-competi-2005-11-7.yml
Normal file
9
_content/OpenOfficeorg-||-A-real-competi-2005-11-7.yml
Normal file
File diff suppressed because one or more lines are too long
7
_content/Pages-2009-4-5.yml
Normal file
7
_content/Pages-2009-4-5.yml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
title: Pages
|
||||||
|
time: 2009-04-05 19:32:16
|
||||||
|
tags:
|
||||||
|
- Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
foo
|
8
_content/Perl-Tip---Chained-encodings-and-2006-10-7.yml
Normal file
8
_content/Perl-Tip---Chained-encodings-and-2006-10-7.yml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
title: Perl Tip - Chained encodings and binmode magic
|
||||||
|
time: 2006-10-07 14:42:04
|
||||||
|
tags:
|
||||||
|
- Perl
|
||||||
|
- Software-Development
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
OK how many of you have gotten those Wide Character in Print warnings while dealing with unicode text? especially UTF-16 files which don't get handled on the fly in perl. I finally figured out how to get rid of them thanks to, of all places, a <a href="http://blogs.msdn.com/brettsh/archive/2006/06/07/620986.aspx">MSDN blog</a>. The gist of the post is a technique where you chain encodings together when changing the encoding used on a file handle. He used it on an open but for my purposes I wanted to change STDOUT's encoding not an opened file handle. So heres the magic line: binmode(STDOUT, ":raw:encoding(UTF-16):utf8"); Now your first thought is why couldn't you just use the encoding you want? Well here's why. First of all the utf8 encoding on the righmost tells perl that it is receiving it's default utf8 encoding. Then the encoding(UTF-16) in the middle performs the encoding conversion and finally the raw on the left tells perl to spit it out whithout changing. The three together result in a warningless conversion from utf8 to utf16 with no line feed conversion. I didn't even know you could chain these together until now but I'm going to remember this trick for the future, that's for sure. To break it all down for you. The chain is processed from right to left. Starting with utf8 got rid of my wide character warning. chaining that into the encoding(UTF-16) performed my conversion and chaining that into :raw made sure I got text and not octet encoded characters.
|
7
_content/Perl-and-CGI-part-I-2005-5-4.yml
Normal file
7
_content/Perl-and-CGI-part-I-2005-5-4.yml
Normal file
File diff suppressed because one or more lines are too long
9
_content/RAP-with-me-now-2005-9-8.yml
Normal file
9
_content/RAP-with-me-now-2005-9-8.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
title: RAP with me now...
|
||||||
|
time: 2005-09-08 02:19:36
|
||||||
|
tags:
|
||||||
|
- APIs
|
||||||
|
- Software-Development
|
||||||
|
- User-Interface
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
Rapid Application Prototyping, or <abbr title="Rapid Application Prototyping">RAP</abbr>(<em>ing</em>) as I will calling it is a fantastic way to be sure you meet your design goals for a project. Furthermore, with AppKit (<em>my own personal Web Application development Framework</em>), it is greatly simplified through the use of an "advanced" plugin and templating engine. How so, you ask? Well I'll tell you... <strong>Application Logic vs UI Flow</strong> What's the difference in these two things? Application Logic is all about how your application handles user input and data. UI Flow is all about how the User sees and inputs data. When the two are seperated you can work on each without disturbing the other. This allows you to, for instance, quickly prototype your UI screens and workflow without worrying about how that application logic works behind the scenes. That way you can get valuable feedback from customers and assistance in your requirements gathering process. <strong>Templating</strong>: (<em>develop that unique look before you do the behind the scenes stuff</em>) When I first got started in this web development thing I didn't know there was such a thing as templating. I developed logic right alongside my UI. In fact in a lot of ways my UI <em><strong>was</strong></em> driven by my application logic. That meant changing something required recoding and reworking my apps logic. This, while challenging and fulfilling, wasn't a particularly useful way of going about things. It was, however, fashionable at the time and everyone was doing it. Nowadays I've grown up and use a much more efficient system. I build my UI seperately using a templating engine. This lets me attach logic to it later (<em>I can detach logic too, or even rework logicall without once touching the template</em>) . I can change the template (<em>rework or even drop the template all completely</em>) all without once touching the logic or even having any logic behind it. In essence I can create a mockup of the programs UI flow demonstrate it, tweak it, test it and then attach the backend. <abbr title="Rapid Application Prototyping">RAP</abbr> is definitely the way to go. <strong>Plugin Architectures</strong> (<em>add a piece here add a piece there</em>) So you can create your UI without once touching the logic. All well and good you say, but what then? Ahhh, that is the beauty of it. Once you have your UI in place start attaching actions to the UI. Then develop the logic that handles that action. If you framework has plugin functionality then you can do that piece by piece. AppKit dynamically loads the plugin you need to do the action you requested. If no plugin fits the action it will tell you so. Need an action? Develop an interface for it. Think of plugins as the hooks for your UI into the Application. And all you have to do is drop them in one at a time or by the wheelbarrow full if you want. Complete separation of logic and program flow/UI. It's a beautiful thing trust me.
|
6
_content/Read-this-article-2006-4-12.yml
Normal file
6
_content/Read-this-article-2006-4-12.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Read this article
|
||||||
|
time: 2006-04-12 18:52:10
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
<a href="http://www.opinionjournal.com/extra/?id=110008220">http://www.opinionjournal.com/extra/?id=110008220</a> trust me it'll open your eyes on a few things. and yes I know this has absolutely nothing to do with code or even computers but I though it was important.
|
10
_content/Really-liking-the-new-kde4-2009-6-27.yml
Normal file
10
_content/Really-liking-the-new-kde4-2009-6-27.yml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
title: Really liking the new kde4
|
||||||
|
time: 2009-06-27 13:13:20
|
||||||
|
tags:
|
||||||
|
- Site-News
|
||||||
|
- desktop-enviroment
|
||||||
|
- gnome
|
||||||
|
- kde
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
I just recently upgraded my home desktop. It was nearing 10 years in age and desperately whispering to me in my sleep that it wasn't going to last much longer. The new machine is a Quad core AMD phenom with A Gigabyte board and 8 gig of ram. This of course necessitated a new OS to go along with the shiny new hardware, so along comes Ubuntu Jaunty with its 64-bit joy and the shiny new KDE4 desktop. I had previously switched from kde to gnome despite being a kde fan for years because gnome had just begun to feel more cohesive. I still disliked the lack of configurability as compared to gnome but overall gnome felt better. But with the new kde4 I've come back. Plasma and the kde desktop have really upped the game. The whole experience has vastly improved and kde no longer feels like it's lagging behind but has leaped ahead of the competition. If you haven't checked it out yet you should give it a try.
|
6
_content/Response-to-Matt-on-PHP-2007-7-14.yml
Normal file
6
_content/Response-to-Matt-on-PHP-2007-7-14.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: Response to Matt on PHP
|
||||||
|
time: 2007-07-14 19:35:19
|
||||||
|
section: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
I haven't seriously looked at PHP in years having long ago joined the Perl camp. I know I know shame on me. However from that very perspective it has seemed to me that php's biggest problem is the addons. Yes Pear and some of the other frameworks alleviate it somewhat but really PHP looks and acts like a thrown together language. Just look at the function list in the documentation. The various libraries it uses are binary addons . Their is little consistency in useage, naming conventions and almost no namespacing used in it. I'll quote <a href="http://jero.net/articles/php6">Jeroen van der Meer</a>: <blockquote>PHP is basically a collection of extensions which are all put together to form what we have now. However, these extensions change and so does the collection.</blockquote> This is almost completely different from the way every other language does it. You might be able to make the case that Java is like this too but even java uses namespacing and most of the libraries are written in java itself. In a way PHP's worst problem has been it's community of users and the language maintainers enablement of that community. The perl community may seem a bit gruff to a php user but getting a module featured in CPAN takes a little bit more work than it seems getting an addon into the official php distribution took. This actually fosters the bad coding practice most perl and ruby users associate with php coders. PHP <em>may</em> finally be growing up but it's like taking a rebellious child who hasn't been disciplined in years and sending him to bootcamp. He'll have to be dragged kicking and screaming obscenities but hopefully the result will be worth it.
|
85
_content/Reuseable-AJAX-gateways-2005-11-28.yml
Normal file
85
_content/Reuseable-AJAX-gateways-2005-11-28.yml
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
title: Reuseable AJAX gateways
|
||||||
|
time: 2005-11-28 16:13:20
|
||||||
|
tags:
|
||||||
|
- Site-News
|
||||||
|
- APIs
|
||||||
|
- javascript
|
||||||
|
- Software-Development
|
||||||
|
- XML
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
Everyone knows about AJAX these days. You just about can't go anywhere on the net whithout hearing about it. And if you're a coder who want's to know more than just what library you should download to start using it you've probably done a little googling and came up with this site: <a href="http://developer.apple.com/internet/webcontent/xmlhttpreq.html">XMLHttpRequest Objects [developer.apple.com]</a> You even played around with the examples and made a few demo apps then realized. Hey!! How can I make these things reusable without ugly global variables and functions that check to see if the response came back yet? In short: how do I use this in a real app? Apple has done a really good job of showing how the xmlhttprequest object works. They even do a good job of showing some useful ways to use it. But if you're like me you want to go a bit farther. I like reusability. I also don't like using Global variables as a gatekeeper. So lets take a look at how we can make this code a little more reusable. The first thing to do is come up with a way to use multiple different functions as the handler for that onreadystate property. Using the same handler really cramps our style. Additionally having to write all that code to test our object's state is a real drag. It would be nice if we could avoid having to write that for every single function we use as a handler. Here is the solution: Let's start with this function here: <code syntax=js>
|
||||||
|
function loadXMLDoc(url) {
|
||||||
|
req = false;
|
||||||
|
// branch for native XMLHttpRequest object
|
||||||
|
if(window.XMLHttpRequest) {
|
||||||
|
try {
|
||||||
|
req = new XMLHttpRequest();
|
||||||
|
} catch(e) {
|
||||||
|
req = false;
|
||||||
|
}
|
||||||
|
// branch for IE/Windows ActiveX version
|
||||||
|
} else if(window.ActiveXObject) {
|
||||||
|
try {
|
||||||
|
req = new ActiveXObject("Msxml2.XMLHTTP");
|
||||||
|
} catch(e) {
|
||||||
|
try {
|
||||||
|
req = new ActiveXObject("Microsoft.XMLHTTP");
|
||||||
|
} catch(e) {
|
||||||
|
req = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(req) {
|
||||||
|
req.onreadystatechange = processReqChange;
|
||||||
|
req.open("GET", url, true);
|
||||||
|
req.send("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code> Now for this to do what we really need it to we need a couple of different things. That processReqChange function needs to be able to change dynamically. So lets add another function argument that will hold a function passed in to be used here. Like so: <code syntax=js>loadXMLDoc(url, func)</code> then you can change<code syntax=js> req.onreadystatechange = processReqChange;</code> to <code syntax=js>req.onreadystatechange = func;</code> This will allow us to pass any function we want as the state change handler. Don't go deleting that processReqChange function yet though. We still need it. In fact lets take a look at that one right now shall we? <code syntax=js>
|
||||||
|
function processReqChange() {
|
||||||
|
// only if req shows "loaded"
|
||||||
|
if (req.readyState == 4) {
|
||||||
|
// only if "OK"
|
||||||
|
if (req.status == 200) {
|
||||||
|
// ...processing statements go here...
|
||||||
|
} else {
|
||||||
|
alert("There was a problem retrieving the XML data:\n" + req.statusText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code> We need this to keep checking our state and tell us when our response came back. We also need it to use any xmlhttprequest object we want it to. What we don't need it to do is retrieve our response for us. In short we need it to recieve a request object in it's arguments and return a response saying it's ok to process our response. So lets modify it a little shall we? <code syntax=js>
|
||||||
|
function processReqChange(req) {
|
||||||
|
// only if req shows "loaded"
|
||||||
|
if (req.readyState == 4) {
|
||||||
|
// only if "OK"
|
||||||
|
if (req.status == 200) {
|
||||||
|
return 1;
|
||||||
|
// it's safe now go ahead
|
||||||
|
} else {
|
||||||
|
alert("There was a problem retrieving the XML data:\n" + req.statusText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
//it's not safe yet
|
||||||
|
}
|
||||||
|
</code> now when we pass this function a request object it returns 1 when we have our response and 0 when the response is not ready yet. Both of these functions are now reusable. But how exactly do we start using them? I thought you would never ask. lets build an example: <code syntax=js>
|
||||||
|
function append_to_id(el, contents) {
|
||||||
|
var element = document.getElementById(el);
|
||||||
|
//alert('appending: ' + contents.nodeValue );
|
||||||
|
element.appendChild(contents);
|
||||||
|
}
|
||||||
|
function append(url, el) {
|
||||||
|
//alert('starting append operation');
|
||||||
|
var func = function() {
|
||||||
|
if (processReqChange(req)) {
|
||||||
|
var ajax_return = req.responseXML;
|
||||||
|
while (ajax_return.hasChildNodes()) {
|
||||||
|
append_to_id(el, ajax_return.firstChild);
|
||||||
|
ajax_return.removeChild(ajax_return.firstChild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var req= loadXMLDoc(url, func);
|
||||||
|
}
|
||||||
|
</code> In the append function we create a dynamic function that we can pass to our loadXMLDoc function. That dynamic function contains the meat of what we are wanting to do. It uses an if statement that checks our processReqChange function for a valid return. When it gets a valid return the if statement processes our request. It couldn't be any eaiser. you can see full example code here: <a href="http://jeremy.marzhillstudios.com/test/dev/ajax/js/ajax.js">Example Script</a>
|
6
_content/SOAP-or-the-lack-thereof-2006-10-27.yml
Normal file
6
_content/SOAP-or-the-lack-thereof-2006-10-27.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: SOAP or the lack thereof
|
||||||
|
time: 2006-10-27 14:50:44
|
||||||
|
tags: Site-News
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
My first professional experience with pulling data via a Soap Service has proven to be very disappointing. I am fairly sure that SOAP services work very well as long as the company providing them knows what they are doing. This company does not appear to know what they are doing. So for future reference when providing a SOAP Service to someone please include in your description of how to hit it the following items: Namespace URL complete Object description for the call Then don't change these under any circumstances. Don't assume that the people using your Service are going to be using .NET on the client side. The whole point of SOAP is cross platform RPC calls. If your system won't work out of the box with Java or Perl or python clients then you didn't set it up right. Anyway I'm done ranting now. Maybe this next time they will get it right.
|
9
_content/SQL-Stupidity-part-II-2005-9-7.yml
Normal file
9
_content/SQL-Stupidity-part-II-2005-9-7.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
title: SQL Stupidity part II
|
||||||
|
time: 2005-09-07 21:31:35
|
||||||
|
tags:
|
||||||
|
- ANSI-SQL
|
||||||
|
- Data
|
||||||
|
- Software-Development
|
||||||
|
content-type: html
|
||||||
|
content: |
|
||||||
|
I am working on a legacy web application right now that is giving me fits. I'd say about 90% or so of the application is done in SQL. Yes you got that right. The business logic is almost completely written in a huge number of stored procedures, sql functions, and scheduled database tasks. This makes tracking down the parts of your app you are trying to work on very difficult. Every time I turn around there is another stored procedure, function, or scheduled database task that needs tweaking. I'm starting to go a little crazy. The problem is it obfuscates what your application is really doing. You think a perl obfuscation contest produces difficult to follow code? They got nothing on this. I realize stored procedures were the cat's meow at the time but this is beyond all human decency. I have got to start refactoring this thing before it gets out of control.
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user