
jesse at bestpractical
Sep 21, 2006, 5:17 AM
Post #1 of 1
(153 views)
Permalink
|
|
r6017 - in people/jesse: . refactoring refactoring/extract_method
|
|
Author: jesse Date: Thu Sep 21 08:17:54 2006 New Revision: 6017 Added: people/jesse/refactoring/ people/jesse/refactoring/extract_method/ people/jesse/refactoring/extract_method/2006-eurooscon-lightining-talk/ people/jesse/refactoring/extract_method/2006-eurooscon-lightining-talk/oscon-europe.2006.xul people/jesse/refactoring/extract_method/2006-eurooscon-lightining-talk/takahashi.css people/jesse/refactoring/extract_method/2006-eurooscon-lightining-talk/takahashi.js people/jesse/refactoring/extract_method/extract (contents, props changed) Modified: people/jesse/ (props changed) Log: r27709[at]pinglin: jesse | 2006-09-21 14:17:49 +0200 * An example of an extract_method tool for perl Added: people/jesse/refactoring/extract_method/2006-eurooscon-lightining-talk/oscon-europe.2006.xul ============================================================================== --- (empty file) +++ people/jesse/refactoring/extract_method/2006-eurooscon-lightining-talk/oscon-europe.2006.xul Thu Sep 21 08:17:54 2006 @@ -0,0 +1,267 @@ +<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="chrome://global/skin/" type="text/css"?><?xml-stylesheet href="takahashi.css" type="text/css"?><page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" id="presentation" xmlns:html="http:/www.w3.org/1999/xhtml" orient="vertical" onkeypress="Presentation.onKeyPress(event);"> +<html:textarea id="builtinCode" style="visibility: collapse"> +Refactoring Perl +---- +One refactoring +---- +extract_method +---- +Please put on your +Perl Sensitive +Sunglasses now. +---- +How do you go from: +---- + sub do_thing { + my $self = shift; + my $thingy = shift; + + my %args = ( foo => 'bar'); + print "We'll do some stuff"; + + # Pretend this an interesting bit of code + system ($thingy, $args{'foo'}); + $self->log("Ran the user's rm -rf"); + + } +---- +To this: +---- + sub do_thing { + my $self = shift; + my $thingy = shift; + + my %args = ( foo => 'bar'); + print "We'll do some stuff"; + + $self->run_command($thingy,\%args); + } + + sub run_command { + my $self = shift; + my $thingy = shift; + my %args = %{(shift)}; + + # Pretend this an interesting bit of code + system ($thingy, $args{'foo'}); + $self->log("Ran the user's rm -rf"); + } +---- +The hard bit +---- +Writing the signature +---- +(The real hard bit is the polish +to make this generally useful) +---- +Our extracted code +---- + system ($thingy, $args{'foo'}); + $self->log("Ran the user's rm -rf"); +---- +PPI? +---- +Scares me +---- +Regexps? +---- +Too broken +---- +So how do we +get the signature? +---- +I blame Damian +---- +And James Duncan +---- +And Piers Cawley +---- +Piers did this +5 years ago. +---- +He didn't publish. +---- +At least he told me +about on Tuesday. +---- +So. Generating +that signature. +---- +Without PPI and Regexps, +we're kinda screwed, no? +---- +What can +parse Perl5? +---- +Only one thing... +---- +perl +---- +We can use B::! +---- +Only MAD_PROPS +gives you enough +B::Rope +---- +That's 5.9+ only. +---- +So. How to get +that data out +of perl? +---- +{{#tag|Hint:}} Ruby +can not +do this. +---- +{{#i|at least not this way}} +---- +So. let's get our +code compiling. +---- + + # cat > /tmp/xxx + system ($thingy, $args{'foo'}); + $self->log("Ran the user's rm -rf"); +---- + # perl -Mstrict -C /tmp/xxx + Global symbol "$thingy" requires explicit package name at /tmp/xxx line 1. + Global symbol "%args" requires explicit package name at /tmp/xxx line 1. + Global symbol "$self" requires explicit package name at /tmp/xxx line 2. + Execution of /tmp/xxx aborted due to compilation errors. +---- +{{#i|Now}} you can +use the regexps. +---- +Yes, it's a hack. +---- +But it works. +---- +http://fsck.com/~jesse/extract +---- +The code {{#warn|sucks}}. +---- +A bit less than it did. +---- +I've used it to +refactor itself. +---- +Twice +---- +Thanks! +http://fsck.com/~jesse/extract +</html:textarea> +<deck flex="1" id="deck"> +<vbox flex="1" onmousemove="Presentation.onMouseMoveOnCanvas(event);"> +<toolbox id="canvasToolbar"> +<toolbar> +<toolbarbutton oncommand="Presentation.home()" label="|<<" observes="canBack"/> +<toolbarbutton oncommand="Presentation.back()" label="<" observes="canBack"/> +<toolbarbutton oncommand="Presentation.forward()" label=">" observes="canForward"/> +<toolbarbutton oncommand="Presentation.end()" label=">>|" observes="canForward"/> +<toolbarseparator/> +<hbox align="center"> +<textbox id="current_page" size="4" oninput="if (this.value) Presentation.showPage(parseInt(this.value)-1);"/> +<description value="/"/> +<description id="max_page"/> +</hbox> +<toolbarseparator/> +<vbox flex="2"> +<spacer flex="1"/> +<scrollbar id="scroller" align="center" orient="horizontal" oncommand="Presentation.showPage(parseInt(event.target.getAttribute('curpos')));" onclick="Presentation.showPage(parseInt(event.target.getAttribute('curpos')));" onmousedown="Presentation.onScrollerDragStart();" onmousemove="Presentation.onScrollerDragMove();" onmouseup="Presentation.onScrollerDragDrop();"/> +<spacer flex="1"/> +</vbox> +<toolbarseparator/> +<spacer flex="1"/> +<toolbarseparator/> +<toolbarbutton id="toggleEva" label="Eva" type="checkbox" autoCheck="false" oncommand="Presentation.toggleEvaMode();"/> +<toolbarseparator/> +<toolbarbutton label="Edit" oncommand="Presentation.toggleEditMode();"/> +<toolbarbutton oncommand="Presentation.reload();" label="Reload"/> +</toolbar> +</toolbox> +<vbox flex="1" id="canvas" onclick="Presentation.onPresentationClick(event);"> +<spacer flex="1"/> +<hbox flex="1"> +<spacer flex="1"/> +<vbox id="content"> +</vbox> +<spacer flex="1"/> +</hbox> +<spacer flex="1"/> +</vbox> +</vbox> +<vbox flex="1" id="edit"> +<toolbox> +<toolbar> +<toolbarbutton label="New Page" oncommand="Presentation.addPage()"/> +<spacer flex="1"/> +<toolbarseparator/> +<toolbarbutton label="View" oncommand="Presentation.toggleEditMode();"/> +<toolbarbutton oncommand="Presentation.reload();" label="Reload"/> +</toolbar> +</toolbox> +<textbox id="textField" flex="1" multiline="true" oninput="Presentation.onEdit()"/> +<hbox collapsed="true"> +<iframe id="dataLoader" onload="if (window.Presentation) Presentation.onDataLoad();"/> +</hbox> +</vbox> +</deck> +<broadcasterset> +<broadcaster id="canBack"/> +<broadcaster id="canForward"/> +</broadcasterset> +<commandset> +<command id="cmd_forward" oncommand="if (Presentation.isPresentationMode) Presentation.forward();"/> +<command id="cmd_back" oncommand="if (Presentation.isPresentationMode) Presentation.back();"/> +<command id="cmd_home" oncommand="if (Presentation.isPresentationMode) Presentation.home();"/> +<command id="cmd_end" oncommand="if (Presentation.isPresentationMode) Presentation.end();"/> +</commandset> +<keyset> +<key key=" " command="cmd_forward"/> +<key keycode="VK_ENTER" command="cmd_forward"/> +<key keycode="VK_RETURN" command="cmd_forward"/> +<key keycode="VK_PAGE_DOWN" command="cmd_forward"/> +<key keycode="VK_RIGHT" command="cmd_forward"/> +<key keycode="VK_DOWN" command="cmd_forward"/> +<!--key keycode="VK_BACK_SPACE" command="cmd_back"/--> +<key keycode="VK_UP" command="cmd_back"/> +<key keycode="VK_PAGE_UP" command="cmd_back"/> +<!-- +<key keycode="VK_BACK_UP" command="cmd_back"/>--> +<!-- +<key keycode="VK_BACK_LEFT" command="cmd_back"/>--> +<key keycode="VK_HOME" command="cmd_home"/> +<!-- +<key keycode="VK_END" command="cmd_end"/>--> +<key key="n" modifiers="accel" oncommand="Presentation.addPage();"/> +<key key="r" modifiers="accel" oncommand="window.location.reload();"/> +<key key="e" modifiers="accel" oncommand="Presentation.toggleEditMode();"/> +<key key="a" modifiers="accel" oncommand="Presentation.toggleEvaMode();"/> +</keyset> +<script src="takahashi.js" type="application/x-javascript" /> +</page> + +<!-- ***** BEGIN LICENSE BLOCK ***** + - Version: MPL 1.1 + - + - The contents of this file are subject to the Mozilla Public License Version + - 1.1 (the "License"); you may not use this file except in compliance with + - the License. You may obtain a copy of the License at + - http://www.mozilla.org/MPL/ + - + - Software distributed under the License is distributed on an "AS IS" basis, + - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + - for the specific language governing rights and limitations under the + - License. + - + - The Original Code is the Takahashi-Method-based Presentation Tool in XUL. + - + - The Initial Developer of the Original Code is SHIMODA Hiroshi. + - Portions created by the Initial Developer are Copyright (C) 2005 + - the Initial Developer. All Rights Reserved. + - + - Contributor(s): SHIMODA Hiroshi <piro[at]p.club.ne.jp> + - + - ***** END LICENSE BLOCK ***** --> + + Added: people/jesse/refactoring/extract_method/2006-eurooscon-lightining-talk/takahashi.css ============================================================================== --- (empty file) +++ people/jesse/refactoring/extract_method/2006-eurooscon-lightining-talk/takahashi.css Thu Sep 21 08:17:54 2006 @@ -0,0 +1,184 @@ +@charset "UTF-8"; + +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Takahashi-Method-based Presentation Tool in XUL. + * + * The Initial Developer of the Original Code is SHIMODA Hiroshi. + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): SHIMODA Hiroshi <piro[at]p.club.ne.jp> + * + * ***** END LICENSE BLOCK ***** */ + +#canvas { + /* + background: black !important; + color: white !important; + */ + font-weight: bold; + font-family: + "Candara" + "Georgia" + "DejaVu Serif Condensed" + "Arial" + "Bitstream Vera Sans" + "Verdana" + "Apple LiGothic" + "Arial Black" + "Bitstream Vera Sans" + sans-serif !important; +} +#canvas * { + cursor: pointer !important; +} +#canvas image { + width: auto; + height: auto; +} +.link-text { + color: #99CCFF !important; + text-decoration: none !important; +} +.link-text:hover { + color: #CCEEFF !important; +/* border-bottom: dotted 1px; */ +} +.link-text:active { + color: white !important; +} +.s { + text-decoration: line-through; +} +.iu { + text-decoration: underline; + font-style: italic; +} +.ui { +/* text-decoration: underline; */ + font-style: italic; +} +.u { + text-decoration: underline; +} +.i { + font-style: italic; + font-family: "Times New Roman" + "Bitstream Vera Serif" + serif; +} +.c { + font-family: "Anonymous" + "Lucida Console" + "Andale Mono" + "Bitstream Vera Sans Mono" + monospace; +} +.t { + font-style: italic; +} + +.h { + color: #ff0000; +} + +.tag { + color: #33f; +} +.warn { + color: #f00; +} +.att { + color: #9999cc; +} +.key { + color: #00ffff; +} +.hid { + color: #999999; +} +.hidt { + color: #999999; + font-style: italic; +} +.pre { + font-family: "Anonymous" + "Lucida Console" + "Andale Mono" + "Bitstream Vera Sans Mono" + monospace; + padding-bottom: 8px; +} +#canvas[rendering="true"] image { + display: none; +} +#canvas[rendering="true"] *, +#canvas[rendering="true"] .text-link { + color: white !important; +} + + +tabbox, tabpanels, tabpanel { + margin: 0; + padding: 0; +} + + + + +#canvas[eva="true"] { + background: white !important; + color: black !important; + font-family: + "Georgia" + "DejaVu Serif Condensed" + "Apple LiGothic" + "Arial Black" + serif !important; +} +#canvas[eva="true"] .link-text { + color: red !important; + text-decoration: none !important; +} +#canvas[eva="true"] .link-text:hover { + color: pink !important; +} +#canvas[eva="true"] .link-text:active { + color: orange !important; +} +#canvas[rendering="true"] *, +#canvas[rendering="true"] .text-link { + color: black !important; +} + + + + +#canvasToolbar { + position: relative; +} + +.subtitle { + display: none; + font-family: "Kochi Gothic"; + color: yellow; + text-align: center; + font-size: 40px; + background: black; + bottom: 10; + padding-bottom: 10px; + padding-top: 10px; + spacing: 10px; +} Added: people/jesse/refactoring/extract_method/2006-eurooscon-lightining-talk/takahashi.js ============================================================================== --- (empty file) +++ people/jesse/refactoring/extract_method/2006-eurooscon-lightining-talk/takahashi.js Thu Sep 21 08:17:54 2006 @@ -0,0 +1,518 @@ +var Presentation = { + init : function(option){ + this.size = 9; + + this._offset = 0; + this.canvas = document.getElementById('canvas'); + this.content = document.getElementById('content'); + this.textbox = document.getElementById('textField'); + this.deck = document.getElementById('deck'); + this.scroller = document.getElementById('scroller'); + + this.canvas.appendChild(document.createElement('description')); + this.canvas.lastChild.setAttribute('id', "caption"); + this.canvas.lastChild.setAttribute('class', 'subtitle'); + this.toolbar = document.getElementById('canvasToolbar'); + this.toolbarHeight = this.toolbar.boxObject.height; + this.isToolbarHidden = true; + this.toolbar.setAttribute('style', 'margin-top:'+(0-this.toolbarHeight)+'px;margin-bottom:0px;'); + + if(option){ + for(var i in option){this[i] = option[i]} + } + + if (this.readParameter()) { + this.takahashi(); + } + + document.documentElement.focus(); + }, + + takahashi : function(){ + if (!document.title) + document.title = this.data[0].replace(/[\r\n]/g, ' '); + + if(!this.data[this.offset]){ + this.offset = this.data.length-1; + } + document.getElementById("current_page").value = this.offset+1; + document.getElementById("max_page").value = this.data.length; + + this.scroller.setAttribute('maxpos', this.data.length-1); + this.scroller.setAttribute('curpos', this.offset); + + var broadcaster = document.getElementById('canBack'); + if (!this.offset) + broadcaster.setAttribute('disabled', true); + else + broadcaster.removeAttribute('disabled'); + + var broadcaster = document.getElementById('canForward'); + if (this.offset == this.data.length-1) + broadcaster.setAttribute('disabled', true); + else + broadcaster.removeAttribute('disabled'); + + this.canvas.setAttribute('rendering', true); + + var text = this.data[this.offset]. + replace(/^[\r\n]+/g,"").replace(/[\r\n]+$/g,"").replace(/(\r\n|[\r\n])/g,"\n") + .split('\n'); + var range = document.createRange(); + range.selectNodeContents(this.content); + range.deleteContents(); + range.detach(); + + var line; + var newLine; + var uri; + var image_width; + var image_total_width = 0; + var image_height; + var image_total_height = 0; + var image_src; + var code_listing = 0; + + + var labelId = 0; + + for (var i = 0; i < text.length; i++) + { + this.content.appendChild(document.createElement('hbox')); + this.content.lastChild.setAttribute('align', 'center'); + this.content.lastChild.setAttribute('pack', 'center'); + + line = text[i]; + image_width = 0; + image_height = 0; + var subtitle = ''; + + if (line.match(/^~/)) { + subtitle = line.substring(1); + line = ''; + } + + + if (line.match(/^ /)) { + code_listing = 1; + this.content.lastChild.setAttribute('align', 'left'); + this.content.lastChild.setAttribute('class', 'pre'); + line = line.substring(1) + } + while (line.match(/^([^\{]+)?(\{\{ima?ge? +src="([^"]+)" +width="([0-9]+)" +height="([0-9]+)"[^\}]*\}\}|\{\{(([^\|]+)?\||)([^\}]+)\}\})(.+)?/)) + { + if (RegExp.$1) { + this.content.lastChild.appendChild(document.createElement('description')); + this.content.lastChild.lastChild.setAttribute('value', RegExp.$1); + } + newLine = line.substring((RegExp.$1+RegExp.$2).length); + + // Images + if (/^([^\{]+)?\{\{ima?ge? +src="([^"]+)" +width="([0-9]+)" +height="([0-9]+)"[^\}]*\}\}/.test(line)) { + this.content.lastChild.appendChild(document.createElement('image')); + image_src = RegExp.$2; + if (image_src.indexOf('http://') < 0 && + image_src.indexOf('https://') < 0) + image_src = this.dataFolder+image_src; + this.content.lastChild.lastChild.setAttribute('src', image_src); + this.content.lastChild.lastChild.setAttribute('width', parseInt(RegExp.$3 || '0')); + this.content.lastChild.lastChild.setAttribute('height', parseInt(RegExp.$4 || '0')); + image_width += parseInt(RegExp.$3 || '0'); + image_height = Math.max(image_height, parseInt(RegExp.$4 || '0')); + } + + // Styles + // else if (/^([^\{]+)?\{\{#([^\|]+)\|([^\}]+)\}\}/.test(line)) { + else if (/^([^\{]+)?\{\{(#([^\|]+)?\|)([^\}]+)\}\}/.test(line)) { + uri = RegExp.$4; + this.content.lastChild.appendChild(document.createElement('description')); + this.content.lastChild.lastChild.setAttribute('value', uri); + this.content.lastChild.lastChild.setAttribute('class', RegExp.$3); + } + + // Links + else if (/^([^\{]+)?\{\{(([^\|]+)?\||)([^\}]+)\}\}/.test(line)) { + uri = RegExp.$4; + if (uri.indexOf('://') < 0) + uri = this.dataFolder+uri; + this.content.lastChild.appendChild(document.createElement('description')); + this.content.lastChild.lastChild.setAttribute('value', RegExp.$3 || RegExp.$4); + this.content.lastChild.lastChild.setAttribute('href', uri); + this.content.lastChild.lastChild.setAttribute('tooltiptext', uri); + this.content.lastChild.lastChild.setAttribute('statustext', uri); + this.content.lastChild.lastChild.setAttribute('class', 'link-text'); + } + + line = newLine; + } + + if (line) { + this.content.lastChild.appendChild(document.createElement('description')); + this.content.lastChild.lastChild.setAttribute('value', line); + } + + image_total_width = Math.max(image_total_width, image_width); + image_total_height += image_height; + } + + this.content.setAttribute('style', 'font-size:10px;'); + caption = document.getElementById('caption'); + if (subtitle) { + caption.setAttribute('value', subtitle); + } else { + caption.setAttribute('value', ''); + + } + + if (this.content.boxObject.width) { + var canvas_w = this.canvas.boxObject.width; + var canvas_h = this.canvas.boxObject.height-image_total_height; + + var content_w = this.content.boxObject.width; + var new_fs = Math.round((canvas_w/content_w) * this.size); + + if (new_fs > 32) { + new_fs = new_fs - (new_fs % 32) + } + //if (code_listing) { new_fs = 48;} + + this.content.setAttribute('style', 'top: 0'); + this.content.setAttribute('style', 'font-size:'+ new_fs + "px"); + + if (this.content.boxObject.width < image_total_width) { + content_w = image_total_width; + new_fs = Math.round((canvas_w/content_w) * this.size); + this.content.setAttribute('style', 'font-size:'+ new_fs + "px"); + } + + var content_h = this.content.boxObject.height; + if(content_h >= (canvas_h - 70)){ // That 50 is space for subtitles + new_fs = Math.round(((canvas_h-70)/content_h) * new_fs); + this.content.setAttribute('style', 'font-size:'+ new_fs + "px"); + content_h = this.content.boxObject.height; + } + } + this.canvas.removeAttribute('rendering'); + }, + + reload : function() { + if (this.dataPath != location.href) { + var path = this.dataPath; + if (location.href.match(/^https?:/)) { + var request = new XMLHttpRequest(); + request.open('GET', path); + request.onload = function() { + Presentation.textbox.value = request.responseText; + Presentation.data = Presentation.textbox.value.split('----'); + + Presentation.takahashi(); + + path = null; + request = null; + }; + request.send(null); + } + else { + document.getElementById('dataLoader').setAttribute('src', 'about:blank'); + window.setTimeout(function() { + document.getElementById('dataLoader').setAttribute('src', path); + path = null; + }, 10); + } + } + else + window.location.reload(); + }, + + forward : function(){ + this.offset++; + this.takahashi(); + }, + back : function(){ + this.offset--; + if(this.offset < 0){this.offset = 0} + this.takahashi(); + }, + home : function(){ + this.offset = 0; + this.takahashi(); + }, + end : function(){ + this.offset = this.data.length-1; + this.takahashi(); + }, + showPage : function(aPageOffset){ + this.offset = aPageOffset ? aPageOffset : 0 ; + this.takahashi(); + }, + + addPage : function() { + if (this.textbox.value && + !this.textbox.value.match(/(\r\n|[\r\n])$/)) + this.textbox.value += '\n'; + this.textbox.value += '----\n'; + this.onEdit(); + }, + + toggleEditMode : function(){ + this.deck.selectedIndex = (this.deck.selectedIndex == 0) ? 1 : 0 ; + }, + toggleEvaMode : function(){ + var check = document.getElementById('toggleEva'); + if (this.canvas.getAttribute('eva') == 'true') { + this.canvas.removeAttribute('eva'); + check.checked = false; + } + else { + this.canvas.setAttribute('eva', true); + check.checked = true; + } + }, + + onPresentationClick : function(aEvent){ + if (!this.isToolbarHidden) + this.showHideToolbar(); + + switch(aEvent.button) + { + case 0: + var uri = aEvent.target.getAttribute('href'); + if (uri) + window.open(uri); + else { + this.forward(); + document.documentElement.focus(); + } + break; + case 2: + this.back(); + document.documentElement.focus(); + break; + default: + break; + } + }, + onScrollerDragStart : function(){ + this.scroller.dragging = true; + }, + onScrollerDragMove : function(){ + if (this.scroller.dragging) + this.showPage(parseInt(this.scroller.getAttribute('curpos'))); + }, + onScrollerDragDrop : function(){ + if (this.scroller.dragging) { + this.showPage(parseInt(this.scroller.getAttribute('curpos'))); + } + this.scroller.dragging = false; + }, + onEdit : function() { + this.data = this.textbox.value.split('----'); + this.takahashi(); + }, + + onKeyPress : function(aEvent) { + switch(aEvent.keyCode) + { + case aEvent.DOM_VK_BACK_SPACE: + if (this.isPresentationMode) { + aEvent.preventBubble(); + aEvent.preventDefault(); + Presentation.back(); + } + break; + default: + break; + } + }, + + + onToolbarArea : false, + toolbarHeight : 0, + toolbarDelay : 300, + toolbarTimer : null, + isToolbarHidden : false, + onMouseMoveOnCanvas : function(aEvent) { + if (this.scroller.dragging) return; + + this.onToolbarArea = (aEvent.clientY < this.toolbarHeight); + + if (this.isToolbarHidden == this.onToolbarArea) { + if (this.toolbarTimer) window.clearTimeout(this.toolbarTimer); + this.toolbarTimer = window.setTimeout('Presentation.onMouseMoveOnCanvasCallback()', this.toolbarDelay); + } + }, + onMouseMoveOnCanvasCallback : function() { + if (this.isToolbarHidden == this.onToolbarArea) + this.showHideToolbar(); + }, + + toolbarAnimationDelay : 100, + toolbarAnimationSteps : 5, + toolbarAnimationInfo : null, + toolbarAnimationTimer : null, + showHideToolbar : function() + { + if (this.toolbarAnimationTimer) window.clearTimeout(this.toolbarAnimationTimer); + + this.toolbarAnimationInfo = { count : 0 }; + if (this.isToolbarHidden) { + this.toolbarAnimationInfo.start = 0; + this.toolbarAnimationInfo.end = this.toolbarHeight; + } + else { + this.toolbarAnimationInfo.start = this.toolbarHeight; + this.toolbarAnimationInfo.end = 0; + } + this.toolbarAnimationInfo.current = 0; + + this.toolbar.setAttribute('style', 'margin-top:'+(0-(this.toolbarHeight-this.toolbarAnimationInfo.start))+'px; margin-bottom:'+(0-this.toolbarAnimationInfo.start)+'px;'); + + this.toolbarAnimationTimer = window.setTimeout('Presentation.animateToolbar()', this.toolbarAnimationDelay/this.toolbarAnimationSteps); + }, + animateToolbar : function() + { + this.toolbarAnimationInfo.current += parseInt(this.toolbarHeight/this.toolbarAnimationSteps); + + var top, bottom; + if (this.toolbarAnimationInfo.start < this.toolbarAnimationInfo.end) { + top = this.toolbarHeight-this.toolbarAnimationInfo.current; + bottom = this.toolbarAnimationInfo.current; + } + else { + top = this.toolbarAnimationInfo.current; + bottom = this.toolbarHeight-this.toolbarAnimationInfo.current; + } + + top = Math.min(Math.max(top, 0), this.toolbarHeight); + bottom = Math.min(Math.max(bottom, 0), this.toolbarHeight); + + this.toolbar.setAttribute('style', 'margin-top:'+(0-top)+'px; margin-bottom:'+(0-bottom)+'px'); + + if (this.toolbarAnimationInfo.count < this.toolbarAnimationSteps) { + this.toolbarAnimationInfo.count++; + this.toolbarAnimationTimer = window.setTimeout('Presentation.animateToolbar()', this.toolbarAnimationDelay/this.toolbarAnimationSteps); + } + else + this.isToolbarHidden = !this.isToolbarHidden; + }, + + + + get offset(){ + return this._offset; + }, + set offset(aValue){ + this._offset = parseInt(aValue || 0); + document.documentElement.setAttribute('lastoffset', this.offset); + return this.offset; + }, + + get data(){ + if (!this._data) { + // Make sure you break the text into parts smaller than 4096 + // characters, and name them as indicated. Tweak as required. + // (What a hack. A JS programmer should find a better way.) + // Luc St-Louis, and email is lucs[at]pobox.com. + + nodes = document.getElementById('builtinCode').childNodes; + content = ''; + for (i in nodes) { + if (nodes[i].nodeValue) { + content = content + nodes[i].nodeValue; + } + } + + this._data = content.split("----"); + } + + return this._data; + }, + set data(aValue){ + this._data = aValue; + return aValue; + }, + + + get isPresentationMode(){ + return (this.deck.selectedIndex == 0); + }, + + + get dataPath(){ + if (!this._dataPath) + this.dataPath = location.href; + return this._dataPath; + }, + set dataPath(aValue){ + var oldDataPath = this._dataPath; + this._dataPath = aValue; + if (oldDataPath != aValue) { + this._dataFolder = this._dataPath.split('?')[0].replace(/[^\/]+$/, ''); + } + return this._dataPath; + }, + + get dataFolder(){ + if (!this._dataFolder) + this.dataPath = this.dataPath; + return this._dataFolder; + }, + set dataFolder(aValue){ + this._dataFolder = aValue; + return this._dataFolder; + }, + + readParameter : function() { + if (location.search) { + var param = location.search.replace(/^\?/, ''); + + if (param.match(/page=([0-9]+)/i)) + this.offset = parseInt(RegExp.$1)-1; + + if (param.match(/edit=(1|true|yes)/i)) + this.toggleEditMode(); + + if (param.match(/eva=(1|true|yes)/i)) + this.toggleEvaMode(); + + if (param.match(/data=([^&;]+)/i)) { + var path = unescape(RegExp.$1); + this.dataPath = path; + if (location.href.match(/^https?:/)) { + var request = new XMLHttpRequest(); + request.open('GET', path); + request.onload = function() { + Presentation.textbox.value = request.responseText; + Presentation.data = Presentation.textbox.value.split('----'); + + Presentation.takahashi(); + }; + request.send(null); + } + else { + document.getElementById('dataLoader').setAttribute('src', path); + } + return false; + } + } + return true; + }, + onDataLoad : function() { + if (!window.frames[0].document.body.hasChildNodes()) return; + var data = window.frames[0].document.body.firstChild.innerHTML; + if (!data) return; + + this.textbox.value = data; + this.data = this.textbox.value.split('----'); + + this.takahashi(); + } +}; + +function init() +{ + window.removeEventListener('load', init, false); + + Presentation.init(); +} +window.addEventListener('load', init, false); Added: people/jesse/refactoring/extract_method/extract ============================================================================== --- (empty file) +++ people/jesse/refactoring/extract_method/extract Thu Sep 21 08:17:54 2006 @@ -0,0 +1,87 @@ +perl; + +use warnings; +use strict; +use IO::All; + +my $code =join('',<STDIN>); + +print extract_method($code); + +sub extract_method { + my $code = shift; + write_file($code); + my $err = 1; + my @args = (); + while ($err) { + $err = 0; + open( my $perl, "-|", 'perl -C /tmp/code.txt 2>&1' ) + || die $@; + while ( my $item = <$perl> ) { + if ( $item + =~ /Global symbol "(.*)" requires explicit package name/ ) + { + $err = 1; + push @args, $1 unless (grep {$1 eq $_} @args); + } + } + write_file($code, @args); + } + return codegen($code,'final',@args); +} + +sub write_file { + my $code = shift; + my @args = (@_); + codegen($code, 'test', @args) > io('/tmp/code.txt'); + +} + +sub codegen { + my $code = shift; + my $mode = shift; + my @args = (@_); + + my $selforthis_signature = qr/^(\$self|\$this)$/; + my ($class_obj) = grep { $_ =~ /$selforthis_signature/ } @args; + my @params = grep { $_ !~ /$selforthis_signature/ } @args; + my $method_body = generate_signature( $class_obj, \@params, $code ); + my $subname = 'mysub_' . int( rand(1000) ); + my $invocation; + if ($class_obj) { + $invocation = $class_obj . "->" . $subname; + } else { + $invocation = $subname; + } + my $ret = "$invocation(" + . join( ',', map { $_ =~ /^(\%|\@)/ ? '\\' . $_ : $_ } @params ) + . ");\n"; + $ret .= "sub $subname { \n" + . ( $mode eq 'test' ? "use strict;\n" : '' ) + . $method_body . "\n}"; + return $ret; +} + +sub generate_signature { + my $class_obj = shift; + my @params = @{(shift)}; + my $code = shift; + + my $ret = join( + "\n", + ( $class_obj ? ' my '.$class_obj." = shift;" :""), + map { + my $var = $_; + if ( $var =~ /^(\%|\@)(.*)$/) { + my $sigil = $1; + my $name = $2; + " my ".$var." = ".$sigil."{(shift)};"; + } else { + " my $var = shift;"; + } + } @params + ) + . "\n\n" + . $code; + return $ret; +} _______________________________________________ Rt-commit mailing list Rt-commit[at]lists.bestpractical.com http://lists.bestpractical.com/cgi-bin/mailman/listinfo/rt-commit
|