CINXE.COM
Tech Stuff - Ruby
<!DOCTYPE html> <html lang="en-us"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <link rel="icon" href="http://www.zytrax.com/favicon.ico"> <title>Tech Stuff - Ruby</title> <!-- this page originated from http://www.zytrax.com/tech/lang/ruby/ --> <!-- HTTP_USER_AGENT=Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.0.04506; .NET CLR 3.5.21022; .NET CLR 1.0.3705; .NET CLR 1.1.4322) --> <style type="text/css"> <!-- /* ZYTRAX STYLE SHEET */ /* google maps */ /* v\:* {behavior:url(#default#VML);} */ /* tag modifiers */ a {text-decoration:none;color:gray;} a:hover {text-decoration:underline;} a:hover.p-f-s {color:black} a:hover.a-n {text-decoration:none;} body {background-color:white;color:black;margin:0px;padding:0px;font:normal 1.0em Verdana,Arial, Helvetica, sans-serif;} code {border:1px solid lightgray;background:mintcream;color:black;font-family:"Courier New", monospace;padding:0 2px} div.l-f table{width:100%;padding:4px;} h1 {font-size:1.5em;;border-width:0 0 5px 0;border-style:solid;border-color:LightGray;padding:4px;color:black} h2 {border-width:0 0 5px 0;border-color:LightGray;border-style:solid;font-size:1.3em;font-weight:bold;padding:4px;color:black} h3 {border-width:0 0 3px 0;border-color:LightGray;border-style:solid;font-size:1.1em;padding:4px;color:black;} h4 {border-width:0 0 2px 0;border-color:LightGray;border-style:solid;font-size:1.0em;padding:2px;color:black;} h5 {border-width:0 0 2px 0;border-color:LightGray;border-style:solid;font-size:1.0em;font-weight:bold;color:black;padding:4px;} h6 {border-width:0 0 1px 0;border-color:LightGray;border-style:solid; font-size:80%;color:black;padding:4px;} pre {white-space:pre-wrap;} img {border:0;} img.center {display:block;margin-left:auto;margin-right:auto;} img.right {display:block;float:right;} img.left {display:block;float:left;} form {border:1px solid #ccc;} input {border:1px solid #999;background:#9bf;} textarea {border:1px solid #999;background:#9bf;} table {margin: 0 auto;} table.t-m-n > tbody > tr > td {border:1px solid #ccc;padding:4px;} table.t-m-s > tbody > tr > td {border:1px solid #ccc;padding:4px;} table.p-m-n > tbody > tr > td {padding:4px;border-collapse:collapse;} table.p-m-s > tbody > tr > td {padding:4px;border-collapse:collapse;} tr {vertical-align:top;} /* end tag modifiers - Printer friendly */ .adv {margin-right:auto;margin-left:auto;width:728px;} .l-b {position:absolute;top:0px;left:0px;font-size:80%;border:0;background:white;color:gray;height:100px;z-index:9;width:100%;} div.l-r #layout {visibility:visible;} div.l-l-fp #layout {visibility:visible;} .l-l {position:absolute;top:100px;left:6px;width:110px;font:10pt Verdana,Helvetica, Arial, sans-serif;z-index:1;} .l-c {margin:105px 170px 0px 125px;padding:4px 20px;border-width:0 1px; border-style:solid; border-color:LightGray; z-index:5; line-height:1.3em;} .l-r {position:absolute;top:100px;right:0;width:160px;background:white;z-index:2;font-size:80%;} /* end printer friendly - begin divs generic (cross browser) */ .i-2 {background: url(../../images/info.gif) no-repeat top left;border-width: 3px 0 3px 0; border-style:solid;border-color:#bbb;font-size:10pt;padding:10px 10px 10px 60px;margin:10px;} .i-3 {background: url(../../../images/info.gif) no-repeat top left;border-width: 3px 0 3px 0; border-style:solid;border-color:#bbb;font-size:10pt;padding:10px 10px 10px 60px;margin:10px;} .l-c-i {padding:10px;} .l-l-fp {position:absolute;top:95px;left:6px;width:120px;z-index:10;text-align:right;font-size:80%;} .l-r-fp {position:absolute;top:95px;right:6px;width:150px;z-index:2;font-size:80%;} .l-f-m {} .l-f {margin:0 200px 0 125px;} .l-p {margin:10px;padding:4px;font:10pt Verdana,Helvetica, Arial, sans-serif;} .l-100 {width:100%;margin:0;} .w-2 {background: url(../../images/warning.gif) no-repeat top left;border-width: 3px 0 3px 0; border-style:solid;border-color:#bbb;font-size:10pt;padding:10px 10px 10px 60px;margin:10px;} .w-3 {background: url(../../../images/warning.gif) no-repeat top left;border-width: 3px 0 3px 0; border-style:solid;border-color:#bbb;font-size:10pt;padding:10px 10px 10px 60px;margin:10px;} /* end divs - begin nav pop-outs */ .n-l-c {color:black;} .n-l1 {padding:0;margin:0;list-style:none;width:100px;} .n-l1p {padding:0;margin:0;list-style:none;text-align:right;color:#339;} .n-l1p-e {font-size:9pt;margin:0;text-align:right;line-height:1.2em;position:relative;color:#339;} .n-l1-e {text-align:right;margin:0;padding:2px;position:relative;} .n-t1-e,.n-t2-e,.n-t3-e,.n-m-l1 {text-align:left;margin:0;padding:2px 5px;border:1px solid black;border-width:1px 1px 0 1px;position:relative;} .n-t1-es,.n-t2-es,.n-t3-es {text-align:left;margin:0;padding:2px 5px;border:1px solid black;border-width:1px 1px 0 1px;position:relative;background:#eee;} .n-t1-v {position:absolute;display:none;padding:0;margin:0;list-style:none;top:100%;right:0;width:100px; border-bottom:1px solid black;background:white;} .n-t1-vr,.n-m-u1 {position:absolute;display:none;padding:0;margin:0;list-style:none; top:100%;right:0;width:100px;border-bottom:1px solid black;background:white;} .n-t2,.n-t3 {position:absolute;display:none;padding:0;margin:0;list-style:none;top:0;right:100%;width:120px;border-bottom:1px solid black;background:white;} /* end pop-up styles - begin nav effects */ .g-c-n:hover {background:#eee;} .g-c-s:hover {background:#eee;} /* W3c pop-ups - selectors ignored by MSIE 6- */ div.n-m:hover > ul {display:block;} div.n-t0:hover > ul {display:block;} li.n-t1-e:hover > ul {display:block;} li.n-t1-es:hover > ul {display:block;} li.n-t1-e:hover, li.n-t1-es:hover,li.n-t2-e:hover,li.n-t2-es:hover,li.n-t3-e:hover,li.n-m-l1:hover {background:#ccc;} li.n-t2-e:hover > ul {display:block;} li.n-t2-es:hover > ul {display:block;} .n-l1-e:hover > ul {display:block;} .n-l1p-e:hover > ul {display:block;} .n-l1-es:hover > ul {display:block;} .n-l2-e:hover > ul {display:block;} .n-l2-es:hover > ul {display:block;} .n-l3-e:hover > ul {display:block;} .n-l3-es:hover > ul {display:block;} li.n-l1-e:hover,li.n-l1p-e:hover,li.n-l2-e:hover,li.n-l2-es:hover, li.n-l3-e:hover, li.n-l3-es:hover,li.n-l4-e:hover {background:#ccc;} /* end pop-up effects - begin generic (cross browser) alpha */ .arrows {font-size:250%;} .a-n {text-decoration:none;} .at {font-family:Verdana,sans-serif;font-size:9pt;margin:0px;text-indent:8px;} .b-1 {font-family:Verdana, sans-serif;} .button {background:#ddd;border:3px outset black;} .b-lg {background-color:#eee;} .b-r {border-width:0 0 0 1px;border-color:#336;border-style:solid;width:150px;} .b-l {border-width:0 1px 0 0;border-color:#336;border-style:solid;width:110px;} .b-b-s {border:1px solid black;} /* color styles */ .c-r, .red {color:red;} .c-b, .blue {color:blue;} .c-lg {color:LightGray;} .c-g {color:gray;} /* end color styles */ .d {font-family:Verdana,sans-serif;font-size:9pt;margin:0px;} .dd {position:absolute;left:0;top:0; font-family:Tahoma,sans-serif;font-size:9pt; visibility:hidden;background:lime;color:black;margin:0px;border:black solid 1px;padding:2px;} .f-d {font-weight:bold;} .f-b-n {border:0;} /* most browsers use an unacceptably small monospace default font */ .g-c-n,.g-b-n {font:110% "Courier New",monospace;border-style:solid;border-color:#ccc;border-width: 1px 1px 1px 5px;background-color:#9bf;padding:5px; color:black;} .g-c-s,.g-b-s,.codegray {font: 80% "Courier New",monospace;border-style:solid;border-color:#ccc;border-width: 1px 1px 1px 5px; background-color:#9bf;padding:5px; color:black;width:inherit;} .g-h-n, .g-s-b {background:#9bf;color:#339;padding:4px;font-size:100%;font-weight:normal;border:1px solid #ccc;} .g-h-nn {background:#9bf;color:#339;padding:4px; font-size:100%;font-weight:normal;} .g-h-ng,.section {background:#339;color:white;font:bold Verdana,sans-serif;padding:4px; text-decoration:none;} .g-h-s {background:#9bf;color:#339;padding:4px; font-size:80%;font-weight:normal;border:1px solid #ccc;} .g-h-ss {background:#9bf;color:#339;padding:4px; font-size:80%;font-weight:normal;} .g-n {text-decoration:none;color:white;} .g-i1-n {margin:5px 5px 5px 20px;} .g-i2-n {margin:5px 5px 5px 30px;} .g-i3-n {margin:5px 5px 5px 40px;} .g-l-n {list-style:none;} .g-sb-n {color:blue;font-size:8pt;line-height:150%;margin:2px;} .g-s-n {background-color:#eee;color:black;font-size:10pt; text-decoration:none;} .h-b {background:#ddd;color:black;font-weight:bold;} .h-150 {line-height:1.5em;} .i-h {margin:5px 5px 10px 60px;padding:5px;} .i-n {border-width: 3px 0 3px 0; border-style:solid;border-color:#bbb;font-size:10pt;padding:10px 10px 10px 60px;margin:10px;} .i-s {border-width: 3px 0 3px 0; border-style:solid;border-color:#bbb;font-size:8pt;margin:10px 10px 10px 60px;padding:10px;} .i-u {width:27px;} .n-l {position:fixed;left:6px;width:110px;} .n-l-fp {left:6px;width:110px;} .n-l-f {font-size:1.0em;margin:2px;text-align:right;line-height:1.2em;color:black;} .n-l-f a {color:black;} .m-h5 {margin:0.5em 0;} .m-h20 {margin:2.0em 0;} .n-b-l {font:1pt Verdana, Arial, Helvetica, sans-serif;border-width:0 0 1px 0;border-style:solid;border-color:#CCF;margin:0px;padding:0px;} .n-l-s {font-size:80%;visibility:hidden;} .n-m {font-size:130%;margin:0;padding:0;float:right;position:relative;} .n-t0 {float:right;position:relative;} .n-t-t {text-align:right;padding:1px 1px 8px 1px;margin:0;} .o-n {list-style:none;} .p-b {background:#eee;text-indent:3em;} .p-m-n,.norm {font-size: 100%;border-spacing:0;border-collapse:collapse;} .p-m-s { font-size:80%;border:0;border-spacing:0;border-collapse:collapse;} .q-i-2 {background: url(../../images/quotes-open.gif) no-repeat top left;} .q-s {border-width: 0 0 0 6px;border-style:solid;border-color:#acf;font-size:8pt;margin:10px 10px 10px 60px;padding:10px;} .t-b-s {font:8pt "Courier New",monospace;border-style:solid;border-color:#ccc;border-width: 1px;background-color:#acf;padding:5px; color:black;} .t-b-n {font:10pt "Courier New",monospace;border-style:solid;border-color:black;border-width: 1px;background-color:#acf;padding:5px; color:black;} /* link/href styles */ .t-dd:hover {background:#ddd;} .w-db:hover {background:#ddd;} .t-ba {color:#aaa;font-weight:bold;} .t-gb {color:blue;background:#eee;} .t-dr {color:red;text-decoration:none;} .t-dw {color:#666;text-decoration:none;} .t-db,.t-dd {color:blue;text-decoration:none;} .t-da {color:black;} .w-db,.t-dn {text-decoration:none;} /* begin text styles */ .t-b {font-size:120%;} .t-b200 {font-size:200%;} .t-c, .center {text-align:center;} .t-g {background:#eee;} .t-h {} div.t-h:hover > div {display:block;} .t-h-1 {display:none;background:#eee;padding:5px;} .t-i {font-style:italic;} .t-l {text-align:left;} .t-n, .g-e-t, .g-e-d {font-size:100%;font-weight:normal;} .t-o {font-weight:bold;} .t-r {text-align:right;} .t-s {font-size:80%;} .t-ss {font-size:60%;} /* table styles */ .t-t-l {margin:0;} .t-td1-l,.t-td1 {border-style:solid;border-width:5px 0 0 0;border-color:#ddd;padding:3px 3px 8px 5px;} .t-td2-l,.t-td2 {border-style:solid;border-width:5px 0 0 0;border-color:#acf;padding:3px 3px 8px 5px;} .t-m {background:#ccc;color:blue;text-decoration:none;} .t-m-n {font-size: 100%;border: 2px solid #ccc;border-spacing:0;border-collapse:collapse;} .t-m-s {font-size:80%;border: 2px solid #ccc;border-spacing:0;border-collapse:collapse;} .vital {font-family:Tahoma,Arial, sans-serif;font-size:12pt;background-color:#ddd; color:black;border-color:red;} /* visibility */ .v-h {visibility:hidden;} /* width styles */ .w-450 {width:450px;} .w-350 {width:350px;} .w-300 {width:300px;} .w-250 {width:250px;} .w-200 {width:200px;} .w-180 {width:180px;} .w-150 {width:150px;} .w-120 {width:120px;} .w-100 {width:100px;} .w-80 {width:80px;} .w-88 {width:88px;} .w-50 {width:50px;} .w-32 {width:32px;} .w-27 {width:27px;} .w-20 {width:20px;} .w-10 {width:10px;} .w-11pc {width:11%;} .w-6pc {width:6%;} /* Gecko/W3C specific */ abbr[title]:after {content:"";} abbr[title]:hover:after {content:" (" attr(title)")";} /* W3C pop-ups */ .n-l2,.n-l3,.n-l4 {position:absolute;display:none;padding:0;margin:0;list-style:none;top:0;left:100%;width:120px;border-bottom:1px solid black;background:#EEE;font:8pt Verdana,Helvetica, Arial, sans-serif} .n-l2-e,.n-l3-e,.n-l4-e {text-align:left;margin:0;padding:2px 5px;border:1px solid black;border-width:1px 1px 0 1px;position:relative;} .n-l2-es,.n-l3-es,.n-l4-es {text-align:left;margin:0;padding:2px 5px;border:1px solid black;border-width:1px 1px 0 1px;position:relative;background:white;} /* end - start expand divs */ .v-f {display:none;} .v-o {display:block;} /* end expand divs */ #toplogo {float:left;vertical-align:bottom;} .g-ci-s {font:8pt "Courier New",monospace;border-style:solid;border-color:#ccc;border-width: 1px 1px 1px 5px; background-color:#acf;color:black;} .jp-h-n {position:absolute;left:50%;top:50%;text-indent:4px;font-family:Verdana,sans-serif;font-size:10pt; visibility:hidden;background:#EEEEEE;color:blue;text-decoration:none;} .n-l-u {font-family:Verdana,sans-serif;top:60px;left:6px;width:110px;background:white;} .n-l-l {font-size: 9pt;color:black;text-align:right;line-height:150%;} .n-p-f {color:#336;font:9pt/16pt Verdana,sans-serif;text-decoration:none;text-indent:6px;} .n-p-n {background:#EEE;color:#336;font:9pt Verdana,sans-serif;text-indent:6px;} .n-p-n a {text-indent:6px;display:block;} .n-p-o {font:10pt Verdana,sans-serif; background:#DDD;color:blue;text-decoration:none;height:16pt;} .n-t-n {color:#336;font:10pt Verdana,sans-serif;text-decoration:none;margin:0;padding:0;} .n-t-s {color:white;font: 8pt Verdana,sans-serif;text-decoration:none;padding:0 3px 0 0} .n-t-sr {color:#336;font: 8pt Verdana,sans-serif;text-decoration:none;padding:0 3px 0 0} .p-b-h {visibility:hidden;} .p-n-h {position:absolute;left:0;top:0;text-indent:4px;font-family:Verdana,sans-serif;font-size:small; visibility:hidden;background:#EEE;color:blue;text-decoration:none;border:1px blue solid;width:110px;} .p-f-s {font-family: Verdana, sans-serif; font-size:8pt; color:silver; background:white;text-decoration:none;} --> </style> <style type="text/css" media="print"> <!-- /* ZYTRAX STYLE SHEET PRINT TEMPLATE */ .l-l {display:none;} .l-r {display:none;} .l-c {width:600px;margin:0;padding:30px 10px 5px 10px; border-width:0;} .l-f {margin:5px;} .n-t-t {display:none;} .n-t0 {display:none;} .adv {display:none;} --> </style> <script type="text/javascript"> <!-- // copyright ZYTRAX, Inc. 1994 - 2014 // you may use this javascript code at your own risk. // we would like you to keep the copyright statement intact but don't insist on it. // If you make improvements mail us a copy or make it available on your own web site. // global variables var topall = new Array(2); var lownav = new Array(2); var lowpop = new Array(2); var rightnav = new Array(2); var rightpop = new Array(2); var x = 0; // global menu level var way = 'h'; var menu = null; var menus = null; var pop1 = new Array(2); var fs = 1.0; var days = new Array(7); var months = new Array(12); days = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]; months = ["January","February","March","April","May","June","July","August","September","October","November","December"]; function showtime() { var thistime = ""; var nowtime ="" var nowam = "AM"; var now = new Date(); var nowhour = now.getHours(); if (nowhour > 12) { nowam = "PM"; nowhour = nowhour - 12; } else if (nowhour == 0){ nowhour = 12; } var nowminutes = now.getMinutes(); if (nowminutes < 10 ){ nowminutes = "0" + nowminutes; } nowtime = nowhour + ":" + nowminutes + " " + nowam; thistime = days[now.getDay()] + " " + now.getDate() + " " + months[now.getMonth()] + " " + now.getFullYear() + ", " + nowtime; return thistime; } // -- W3C DOM specific code - first choice always function lock(num){ // lock relies on a style which end with -l rollover = document.getElementById("l" + num); if(rollover){ cn = rollover.className if((pos = cn.lastIndexOf("-")) != -1){ bcn = cn.substring(0,pos + 1); scn = cn.substring(pos +1); if(scn == "f" || scn == "o"){ rollover.className = bcn + "l"; } } } } function fontchange(fix) { x = document.getElementsByTagName("div"); for(i = 0; i < x.length; i++) { if(x[i].className == "l-c"){ if(x[i].style.fontSize == ""){ fs = 1.0; x[i].style.fontSize = "1.0em"; } if(fix == "d"){ if(fs <= 0.8){ break; }else{ fs = parseFloat(fs - 0.1); x[i].style.fontSize = fs + "em"; } }else{ if(fs >= 1.5){ break; }else{ fs = parseFloat(fs + 0.1); x[i].style.fontSize = fs + "em"; } } break; } } } function toggle(tid){ var dis; var disa; if(document.getElementById){ dis = document.getElementById(tid); disa = document.getElementById(tid + 'a'); }else{ dis = document.all.tid; disa = document.all.tid + 'a'; } if(dis.style.display == 'block'){ dis.style.display = 'none'; disa.style.display = 'block'; }else{ dis.style.display = 'block'; disa.style.display = 'none'; } } function gotourl($url) { window.location = $url; } function mailus(mbox,stub,subject) { mail = "mailto:"+mbox+"@"+stub; if(subject != ""){ mail = mail+"?SUBJECT="+"A-Z: "+subject; } window.location = mail; return; } // W3C compliant uses CSS popups not JS //--> </script> </head> <body> <!-- Page Header plus top nav bar --> <div class="l-b"> <!--if expr="!${isMob}" --> <a href="http://www.zytrax.com"><img id="toplogo" src="http://www.zytrax.com/images/zytrax-logo-info.png" alt="ZYTRAX Info Logo"></a> <!-- desktop browsers --> <p class="n-t-t"><a href="http://www.zytrax.com/feedback.htm" class="n-t-sr">mail us</a> | <a href="http://www.zytrax.com/run/mailpage.php" class="n-t-sr">mail this page</a></p> <div class="n-t0"> <a href="http://www.zytrax.com/Company/contacts.html" class="n-t-sr">contact us</a> </div> <div class="n-t0"> <a href="http://www.zytrax.com/training/" class="n-t-sr">training</a> | </div> <div class="n-t0"> <a href="http://www.zytrax.com/tech/" class="n-t-sr">tech stuff</a> | <ul class="n-t1-v"> <li class="n-t1-es"><a href="http://www.zytrax.com/tech/" class="t-da">tech stuff</a> <!-- tertiary pop-outs --> <ul class="n-t2"> <li class="n-t2-e"><a title="collection of technology stuff" href="http://www.zytrax.com/tech/" class="t-da">tech stuff</a></li> <li class="n-t2-es t-da">web stuff <ul class="n-t3"> <li class="n-t3-e"><a title="collection of web based technology stuff" href="http://www.zytrax.com/tech/web/" class="t-da">web stuff</a></li> <li class="n-t3-e"><a title="collection of UA strings for most browsers" href="http://www.zytrax.com/tech/web/browser_ids.htm" class="t-da">browser ids</a></li> <li class="n-t3-e"><a title="collection of mobile UA strings" href="http://www.zytrax.com/tech/web/mobile_ids.html" class="t-da">mobile ids</a></li> <li class="n-t3-e"><a title="our HTML5 page conversion process and thoughts" href="http://www.zytrax.com/tech/css/html5.html" class="t-da">HTML5 Convert</a></li> <li class="n-t3-e"><a title="how we do server-side browser sniffing with apache" href="http://www.zytrax.com/tech/web/browser_sniffing.html" class="t-da">browser sniffing</a></li> <li class="n-t3-e"><a title="apache environmental variables" href="http://www.zytrax.com/tech/web/env_var.htm" class="t-da">apache env's</a></li> <li class="n-t3-e"><a title="apache server side includes - extensive notes and examples" href="http://www.zytrax.com/tech/web/ssi.htm" class="t-da">apache ssi</a></li> <li class="n-t3-e"><a title="our css pop-up/pop-down/flyout menus for Gecko/Opera/MSIE" href="http://www.zytrax.com/tech/css/workarounds.html#popout" class="t-da">pop-outs (css)</a></li> <li class="n-t3-e"><a title="most of those annoying HTML entity codes that we forget all the time" href="http://www.zytrax.com/tech/web/entities.html" class="t-da">html entities</a></li> </ul> </li> <li class="n-t2-es t-da">open guides <ul class="n-t3"> <li class="n-t3-e"><a href="http://www.zytrax.com/books/" class="t-da">open guides</a></li> <li class="n-t3-e"><a href="http://www.zytrax.com/books/dns" class="t-da">dns guide</a></li> <li class="n-t3-e"><a href="http://www.zytrax.com/books/ldap" class="t-da">ldap guide</a></li> </ul> </li> <li class="n-t2-e"><a title="Decimal to Hexidecimal to Binary conversion - even Octal!" href="http://www.zytrax.com/tech/protocols/hex.html" class="t-da">Dec>Hex>Bin</a></li> <li class="n-t2-es t-da">survival stuff <ul class="n-t3"> <li class="n-t3-e"><a href="http://www.zytrax.com/tech/survival/" title="a series of survival guides for some popular open source software" class="t-da">survival stuff</a></li> <li class="n-t3-e"><a href="http://www.zytrax.com/tech/survival/ssl.html" class="t-da">ssl/tls & x.509</a></li> <li class="n-t3-e"><a href="http://www.zytrax.com/tech/survival/asn1.html" class="t-da">ASN.1</a></li> <li class="n-t3-e"><a href="http://www.zytrax.com/tech/survival/kerberos.html" class="t-da">kerberos</a></li> <li class="n-t3-e"><a href="http://www.zytrax.com/tech/survival/postfix.html" class="t-da">postfix</a></li> <li class="n-t3-e"><a href="http://www.zytrax.com/tech/survival/cron.html" class="t-da">cron</a></li> <li class="n-t3-e"><a href="http://www.zytrax.com/tech/survival/encryption.html" class="t-da">cryptography</a></li> <li class="n-t3-e"><a href="http://www.zytrax.com/tech/survival/wxwidgets.html" class="t-da">wxWidgets</a></li> </ul> </li> <li class="n-t2-es t-da">audio stuff <ul class="n-t3"> <li class="n-t3-e"><a title="Pages about Digital Audio, Primers, Calculator, Equalization, FFT" href="http://www.zytrax.com/tech/audio/" class="t-da">audio stuff</a></li> <li class="n-t3-e"><a title="Fundamentals, harmonics, overtone, partials, loudness, ADSR envelopes" href="http://www.zytrax.com/tech/audio/sound.html" class="t-da">sound primer</a></li> <li class="n-t3-e"><a title="Sound digitization, time domain, frequency domain" href="http://www.zytrax.com/tech/audio/digital-sound.html" class="t-da">digital sound</a></li> <li class="n-t3-e"><a title="common frequencies of instruments and in life" href="http://www.zytrax.com/tech/audio/audio.html" class="t-da">frequencies</a></li> <li class="n-t3-e"><a title="equalization principles, octaves, sound metering and FFT" href="http://www.zytrax.com/tech/audio/equalization.html" class="t-da">equalization</a></li> <li class="n-t3-e"><a title="Acoustic caculators for musical notes and FFT bin frequencies" href="http://www.zytrax.com/tech/audio/calculator.html" class="t-da">calculators</a></li> <li class="n-t3-e"><a title="Yet another audio glossary" href="http://www.zytrax.com/tech/audio/glossary.html" class="t-da">glossary</a></li> </ul> <li class="n-t2-e"><a href="http://www.zytrax.com/tech/web/regex.htm" class="t-da">regex stuff</a></li> <li class="n-t2-es t-da">cable stuff <ul class="n-t3"> <li class="n-t3-e"><a href="http://www.zytrax.com/tech/layer_1/" class="t-da">cable stuff</a></li> <li class="n-t3-e"><a href="http://www.zytrax.com/tech/layer_1/cables/tech_lan.htm" class="t-da">lan wiring</a></li> <li class="n-t3-e"><a href="http://www.zytrax.com/tech/layer_1/cables/mixed.html" class="t-da">lan & telephone</a></li> <li class="n-t3-e"><a href="http://www.zytrax.com/tech/layer_1/cables/tech_rs232.htm" class="t-da">rs232 stuff</a></li> <li class="n-t3-e"><a href="http://www.zytrax.com/tech/layer_1/cables/heavy.htm" class="t-da">serial primer</a></li> <li class="n-t3-e"><a href="http://www.zytrax.com/tech/pc/serial.html" class="t-da">usb 3.2 & firewire</a></li> <li class="n-t3-e"><a href="http://www.zytrax.com/tech/pc/monitors.htm" class="t-da">displays</a></li> <li class="n-t3-e"><a href="http://www.zytrax.com/tech/layer_1/cables/cables_jacks.htm" class="t-da">modular jacks</a></li> </ul> </li> <li class="n-t2-es t-da">protocol stuff <ul class="n-t3"> <li class="n-t3-e"><a href="http://www.zytrax.com/tech/protocols/" class="t-da">protocol stuff</a></li> <li class="n-t3-e"><a href="http://www.zytrax.com/tech/protocols/tcp.html" class="t-da">tcp-udp-icmp</a></li> <li class="n-t3-e"><a href="http://www.zytrax.com/tech/protocols/ip-classes.html" class="t-da">ipv4</a></li> <li class="n-t3-e"><a href="http://www.zytrax.com/tech/protocols/ip-classes.html#calculator" class="t-da">ipv4 Calculator</a></li> <li class="n-t3-e"><a href="http://www.zytrax.com/tech/protocols/ipv6.html" class="t-da">ipv6</a></li> <li class="n-t3-e"><a href="http://www.zytrax.com/tech/protocols/ipv6.html#calculator" class="t-da">ipv6 Calculator</a></li> <li class="n-t3-e"><a href="http://www.zytrax.com/tech/protocols/isdn" class="t-da">isdn-bri</a></li> <li class="n-t3-e"><a href="http://www.zytrax.com/tech/protocols/lan" class="t-da">802 lan</a></li> <li class="n-t3-e"><a href="http://www.zytrax.com/tech/ss7" class="t-da">ss7 & sigtran</a></li> </ul> </li> <li class="n-t2-e"><a href="http://www.zytrax.com/tech/pc/" class="t-da">pc stuff</a></li> <li class="n-t2-e"><a href="http://www.zytrax.com/tech/wireless/" class="t-da">wireless stuff</a></li> <li class="n-t2-es t-da">css stuff <ul class="n-t3"> <li class="n-t3-e"><a title="collection of css notes and experiences including css menus and css liquid layout" href="http://www.zytrax.com/tech/css/" class="t-da">css stuff</a></li> <li class="n-t3-e"><a title="Notes on our experience with converting to css based liquid layouts - including blow by blow css" href="http://www.zytrax.com/tech/css/layoutnotes.html" class="t-da">css liquid design</a></li> <li class="n-t3-e"><a title="we have used css menus since mid-2003 - blow-by-blow implementation notes" href="http://www.zytrax.com/tech/css/workarounds.html#popout" class="t-da">css menus</a></li> <li class="n-t3-e"><a title="some practical solutions on using css" href="http://www.zytrax.com/tech/css/workarounds.html" class="t-da">css notes</a></li> <li class="n-t3-e"><a title="css shortforms at a glance" href="http://www.zytrax.com/tech/css/shortcut.html" class="t-da">css short-forms</a></li> <li class="n-t3-e"><a title="css selectors and quick overview with links to the W3C specs" href="http://www.zytrax.com/tech/css/syntax.html" class="t-da">css overview</a></li> </ul> </li> <li class="n-t2-e"><a href="http://www.zytrax.com/tech/codes.htm" class="t-da">ascii codes</a></li> <li class="n-t2-e"><a href="http://www.zytrax.com/tech/data_rates.htm" class="t-da">data rate stuff</a></li> <li class="n-t2-e"><a href="http://www.zytrax.com/tech/telephony/" class="t-da">telephony stuff</a></li> <li class="n-t2-e"><a href="http://www.zytrax.com/tech/mech/" class="t-da">mech. stuff</a></li> <li class="n-t2-e"><a href="http://www.zytrax.com/tech/protocols/hex.html" class="t-da">Dec>Hex>Bin</a></li> <li class="n-t2-e"><a href="http://www.zytrax.com/tech/lang/" class="t-da">language stuff</a></li> <li class="n-t2-e"><a href="http://www.zytrax.com/tech/electronics/" class="t-da">electronic stuff</a></li> <li class="n-t2-e"><a href="http://www.zytrax.com/tech/rfcs/" class="t-da">rfc stuff</a></li> </ul> </li> <li class="n-t1-e"><a href="http://www.zytrax.com/security/" class="t-da">Security</a></li> </ul> </div> <!-- close div l-b --> </div> <!-- begin body table --> <div class="l-c"> <!-- generic tech ads --> <p class="adv"> <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <!-- Browser Leaderboard --> <ins class="adsbygoogle" style="display:inline-block;width:728px;height:90px" data-ad-client="ca-pub-9419480011552853" data-ad-slot="9281933980"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </p> <!-- end body table --> <h1>Tech Stuff - Ruby</h1> <p>This a collection of notes and an embryonic glossary about the <b>ruby</b> language. Our chosen language for scripting, application and web development since we saw the light in 2003. Mostly it's about the stupid things that you get badly wrong, were confusing (to us) at the beginning, are obscure or just not IOHO adequately covered in the documentation.</p> <p><b>Note:</b> Languages should be like hammers. Once you learn to use them they should work the same way every time. We note with considerable regret that ruby has embarked on a fool's errand. The making of an incompatible change from 1.8.x to 1.9.x releases in pursuit of the holy grail of language purity. Good luck with that. While the volume of ruby code is still significantly less than that of Python we note that the Python project cheefullfully accepted a 2 to 3 year transition stratgey in 2007 from Version 2 to the incompatible Version 3. Eight years later (2015) they are still mainaining Version 2 and 3 with, frankly, no prospect of ever escaping. Some of Python's function libraries were written by folks who have long since moved on to new work or may even be dead. Give us a healthy dose of language pragmatism (and we'll learn the few exeptions, perhaps even hold our nose while using them) with consistent backward compatibility rather than purism which means every couple of years stuff which used to work - no longer does. Maybe Ruby can get back its mojo - were it not for Ruby on Rails I doubt it. No one will ever trust them again. Shame, it is (or is that, was) a good language.</p> <h4>Glossary Navigation</h4> <p>Select from the range below:</p> <p><a title="" href="glossary.html#symbols-nav" class="t-db">Symbols ?, #, ::, etc.</a> | <a title="" href="gloss-a.html#a-nav" class="t-db">a - d</a> | <a title="" href="gloss-e.html" class="t-db">e - l</a> | <a title="" href="gloss-m.html" class="t-db">m - r</a> | <a title="" href="gloss-s.html" class="t-db">s - z</a></p> <h3 id="contents">Contents - Notes</h3> <ul> <li><a href="#names" class="t-db">ruby, eruby and erb</a></li> <li><a href="#apache" class="t-db">mod_ruby Ruby Apache Configuration</a></li> <li><a href="#errors" class="t-db">Internal Server (500) - Display mod_ruby Errors</a></li> <li><a href="ror.html" class="t-db">Ruby on Rails</a></li> <li><a href="#objects" class="t-db">Ruby Objects, Variables and Constants</a></li> <li><a href="#quotes" class="t-db">Single and Double Quotes</a></li> <li><a href="#forms" class="t-db">Form Variables - Tempfiles and StringIO in cgi.rb</a></li> <li><a href="#upload" class="t-db">File upload</a></li> <li><a href="#convert" class="t-db">Type Conversion</a></li> <li><a href="#iterate" class="t-db">Iteration and blocks</a></li> <li><a href="#stuff" class="t-db">Stuff about objects</a></li> <li><a href="#dirs" class="t-db">Files and Directories</a></li> <li><a href="#files" class="t-db">Files - Reading 'n writing</a></li> <li><a href="#library" class="t-db">Ruby Library and Path Locations</a></li> <li><a href="#each" class="t-db">Implementing an each method in a class</a></li> <li><a href="#fileutils" class="t-db">Notes on using FileUtils.rb </a></li> <li><a href="#resolv" class="t-db">Using Ruby STD-LIB Resolv.rb</a></li> <li><a href="#multi-hash" class="t-db">Using Multi-level hashes</a></li> <li><a href="#multi-return" class="t-db">Returning Multiple Values</a></li> <li><a href="#exceptions" class="t-db">Errors and Exceptions</a></li> <li><a href="#exceptions" class="t-db">mod_ruby and cookies</a></li> </ul> <p><b>Notes:</b> First some notes about our usage and environment:</p> <ol> <li>We chose <b>ruby</b> because we needed a stand-alone language for both application development and to use as a web scripting language. That left us with Perl (parrot), Python and Ruby. We chose <b>ruby</b> because it appears simpler to add C functionality to speed things up.</li> <li>We have decided to completely overhaul our development methodology with <b>ruby</b> as its key component. <ol> <li>Use <b>ruby</b> as a single <b>very high level language (VHLL)</b> to quickly implement 100% functionality - this is not prototyping this is a fully functional system - it may run like a dog but it lets us move the next stage</li> <li>prove (test) system functionality - 100% of functionality. The design - develop feedbackloop occurs at this level</li> <li>Use a profiler to find execution <b>hotspots</b></li> <li>Using the profiler output as a priority list - re-implement ONLY THOSE PARTS of the working design (methods or complete objects) into C as required to meet performance objectives</li> <li>The operational system will be mixed language implementation with all the top-level or control logic visible in <b>ruby</b></li> <li>Fixes and corrections are applied to the original implementation to keep a fully functional system in pure <b>ruby</b> as well as our hybrid final system.</li> </ol> Well that's the theory. We are currently using it to develop a complete web controlled mail system (SMTP, IMAP, POP3) as a full scale implementation exercise.</li> <li>We do development using a windows based HTML Editor-IDE, upload the files using a web page written in <b>ruby</b> and then run them via the same interface. So you'll find these notes very web-centric.</li> </ol> <h2 id="names">ruby, eruby and erb</h2> <p>The following notes may help when you come to look at the Apache configuration files below:</p> <ol> <li>modules directly executed by mod_ruby have .rbx or .rb suffixes (the config below allows both) and are assumed to be pure <b>ruby</b> scripts. i.e they are not contained in HTML. These files are located in /usr/local/www/cgi-ruby/ directory (via ScriptAlias directive) and invoked with urls of .../ruby/name.rb or .rbx.</li> <li>Ruby scripts embedded in HTML files i.e using <%....%> constructs are contained in files with suffixes of .rhtml and use <b>eruby</b>. These files are located in /usr/local/www/eruby/ directory (via ScriptAlias directive) and are invoked with URLs of ../eruby/myruby.rhtml. A scipt may additionally be placed in the normal directory with a suffix of *.rhtml e.g. index.rhtml - this is less secure since the module content may be viewed.</li> <li>Only God seems to know what erb is - certainly google doesn't??</li> </ol> <p><a href="#contents"><img class="i-u" src="../../../images/go_up.gif" alt="GO UP"></a></p> <h2 id="cookies">mod_ruby and cookies</h2> <p>To access cookies from mod_ruby:</p> <pre class="g-c-s"> # writing request.headers_out['Set-Cookie']="user_id=#{@useridx}/#{@confkey}; path=/" # reading request.headers_in['Cookie'].split(';').each do |cookie| k,v = cookie.split(C_equal) k.strip! v.strip! @cookies[k] = v end # or using webrick libraries require 'webrick/cookie' # # misc stuff # # Set a cookie cookie = WEBrick::Cookie.new('user_id','12345') cookie.expires = Time.now + (86400 * 30) cookie.path = '/' request.headers_out['Set-Cookie'] = cookie.to_s # Read cookies cookies = WEBrick::Cookie.parse(request.headers_in['Cookie']) # alternate extend Apache::request with cookies = request.cookies request.cookie = cookie request.cookie = {:key => 'user_id', :value => @user_id, :path => '/', :expires => Time.now + 86400 * 30} </pre> <p><a href="#contents"><img class="i-u" src="../../../images/go_up.gif" alt="GO UP"></a></p> <h2 id="apache">Apache Configuration (httpd.conf)</h2> <p>mod_ruby specific fragment of the httpd.conf file to use both ruby and eruby with 'hooked' error 500 response. <b>Note:</b> the fragment below uses FreeBSD <b>LoadModule</b> libexec/ locations for modules Linux RedHat (and we assume other distributions) uses /modules directory.</p> <pre class="g-b-n"> # Defines Ruby module location LoadModule ruby_module libexec/apache/mod_ruby.so # Defines Ruby as Present AddModule mod_ruby.c # Allows default file name to include index.rhtml <IfModule mod_dir.c> <IfModule mod_php4.c> <IfModule mod_ruby.c> DirectoryIndex index.php index.html index.rhtml </IfModule> <IfModule !mod_ruby.c> DirectoryIndex index.php index.html </IfModule> </IfModule> <IfModule !mod_php4.c> <IfModule mod_ruby.c> DirectoryIndex index.rhtml index.html </IfModule> <IfModule !mod_ruby.c> DirectoryIndex index.php </IfModule> </IfModule> </IfModule> # Defines location for .rbx and .rb format ruby files. ScriptAlias /ruby/ "/usr/local/www/cgi-ruby/" <Directory "/usr/local/www/cgi-ruby"> AllowOverride None Options All Order allow,deny Allow from all </Directory> # Defines cgi location for ruby .rhtml files ScriptAlias /eruby/ "/usr/local/www/eruby/" <Directory "/usr/local/www/eruby"> AllowOverride None Options ExecCGI Order allow,deny Allow from all </Directory> <IfModule mod_ruby.c> # Defines features for ruby scripts eg. .rbx files # for Apache::RubyRun RubyRequire apache/ruby-run # exec files under /ruby as ruby scripts. <Location /ruby> #defines a ruby script will be used to return error code # rather than Internal Error 500 ErrorDocument 500 /ruby/error_500.rb SetHandler ruby-object RubyHandler Apache::RubyRun.instance Options ExecCGI </Location> # exec *.rbx as ruby scripts. <Files *.rbx> SetHandler ruby-object RubyHandler Apache::RubyRun.instance </Files> # exec *.rb as ruby scripts. <Files *.rb> SetHandler ruby-object RubyHandler Apache::RubyRun.instance </Files> # Define features for embedded ruby scripts eg. .rhtml files. # for Apache::ERubyRun RubyRequire apache/eruby-run # # handle files under /eruby as eRuby files by eruby. <Location /eruby> #defines a ruby script will be used to return error code # rather than Internal Error 500 ErrorDocument 500 /ruby/error_500.rb SetHandler ruby-object RubyHandler Apache::ERubyRun.instance Options ExecCGI </Location> # # handle *.rhtml as eruby files. <Files *.rhtml> SetHandler ruby-object RubyHandler Apache::ERubyRun.instance </Files> # for Apache::ERbRun # RubyRequire apache/erb-run # # handle files under /erb as eRuby files by ERb. <Location /erb> SetHandler ruby-object RubyHandler Apache::ERbRun.instance Options ExecCGI </Location> # # for debug # RubyRequire auto-reload </IfModule> </pre> <p><a href="#contents"><img class="i-u" src="../../../images/go_up.gif" alt="GO UP"></a></p> <h2 id="errors">mod_ruby display Real Error Script</h2> <p>mod_ruby does not fail with warnings AND warning messages are NOT written to the log file (e.g. /var/log/apache/error.log or whatever), only error messages are written to this file. So forget about warnings completely under mod_ruby. Maybe there is a diagnostic level you can set but we have not found it.</p> <p>When Ruby has a syntax or other error it returns an 'Internal Server Error (500)' and the error message is written to the apache error log. Not very convenient. To return the real error in the response page use the <b>ErrorDocument</b> feature of Apache and the following script (which would be placed in the error_500.rb file referenced in the http.conf file fragment above). Note: If you are using MSIE it intercepts error pages and gives you one of its own - so use a decent browser e.g. any of the Mozilla family):</p> <pre class="g-b-n"> r = Apache.request r.content_type = "text/plain" r.send_http_header print "Ruby Error: ",r.prev.uri,"\n\n" print r.prev.error_message </pre> <p>When a error occurs (but not a warning) the actual failure message is displayed on the returned page.</p> <p><a href="#contents"><img class="i-u" src="../../../images/go_up.gif" alt="GO UP"></a></p> <h2 id="objects">Ruby Objects, Constants and Variables</h2> <p>In Ruby everything is an object? Actually in Ruby we have Objects and references to objects (variables). There are 2 types of Variables. Constant varibles which we'll refer to as constants and regular variables which we'll just call variables.</p> <pre class="g-b-n"> arr = ["a", "b", "c"] # arr is a variable that has been assigned # the address of a dynamically created array Object B = "Hello" # B is a constant that has been assigned # the address of a dynamically created String Object </pre> <h2 id="freeze">Freezing Objects</h2> <p>The idea of freezing an object is to make the object unmodifiable<br>Example:</p> <pre class="g-b-n"> arr = [ "a", "b", "c" ] arr.freeze # This freezes the array object, not the variable puts arr # output => a, b, c arr[0] = "3" # This produces an error since the array object is frozen # we cannot change its contents Note: But the variable arr can be reassigned to another object arr = [ "1","2","3"] # This works fine no error here </pre> <p><a href="#contents"><img class="i-u" src="../../../images/go_up.gif" alt="GO UP"></a></p> <h2 id="constants">Constants vs. Variables</h2> <P>All constants must begin with a Capital letter. Reassigning a constant from one object to another gives a warning, but the reassignment is done anyway.</p> <pre class="g-b-n"> Bill = "Hello" # Bill is a Constant bill = "Hello" # bill is a variable Bill= "Bye" # Gives a Warning bill = "Bye" # Gives no warning </pre> <p><a href="#contents"><img class="i-u" src="../../../images/go_up.gif" alt="GO UP"></a></p> <h2 id="quotes">Double (" " ) vs. Single (' ') Quotes</h2> <p>Enclosing strings in double quotes allows you to use escapings to represent ASCII and Unicode characters. Single quotes allow simple \ escapings only.</p> <pre class="g-b-n"> puts "bill\n\r" # => bill puts 'bill\n\r' # => bill\n\r puts "abcd #{5*3} efg" # => abcd 15 efg puts 'abcd #{5*3} efg' # => abcd #{5*3} efg # simple escapings in single strings puts 'outputs \' single quote' </pre> <p><a href="#contents"><img class="i-u" src="../../../images/go_up.gif" alt="GO UP"></a></p> <h3 id="forms">Form Variables - Tempfile, StringIO and Strings in cgi.rb</h3> <p>This one cost serious blood - well the bad cold did not help. IOHO cgi.rb is a bit confusing and inconsistent in behaviour - maybe that explains why there are multiple alternatives.</p> <p>Depending on how you access the form variables will depend on the results you get.</p> <ol> <li>An explicit request in 1.8.x of form cgi['myvar'] returns a string</li> <li>pre 1.8.x it returns an array</li> <li>If you use the form cgi.params it returns a hash</li> <li>If your form happens to include file upload (e.g. contains <input type="file"> and an 'enctype="multipart/form-data"') then the fun really starts because: <ul> <li>if the file size is > 10240 bytes ALL variables are created as Tempfiles</li> <li>if < 10240 they are StringIO objects.</li> </ul> </li> <li>So depending on what is arriving cgi variables can appear as any of a String, StringIO or Tempfile.</li> </ol> <pre class="g-b-n"> # code fragment to test for cgi variable type require 'cgi' require 'stringio' thing = cgi['myvar'].first # gets specific variable if thing.kind_of? StringIO puts cgi['myvar'][0].string # or puts thing.string #to_s doesn't hack it elsif thing.kind_of? Tempfile # get as Tempfile puts thing.read elsif thing.kind_of? String puts thing else puts "ERROR:"+thing.class end </pre> <p><a href="#contents"><img class="i-u" src="../../../images/go_up.gif" alt="GO UP"></a></p> <h2 id="upload">mod_ruby File upload scripts</h2> <p>To upload a file in eruby.</p> <pre class="g-b-s"> <!-- HTML form fragment --> <form name='fileupload' enctype="multipart/form-data" action='/eruby/upload.rhtml' method='post'> <input type='file' name='myfile' size="40" /> <input type='submit' value"Send it"/> </form> # ruby script fragment require 'cgi' require 'stringio' cgi = CGI.new() # New CGI object # get uri of tx'd file (in tmp normally) tmpfile = cgi.params['myfile'].first.path # OR (functionally the same) tmpfile = cgi.params['myfile'][0].path # or - this again is the same tmpfile cgi['myfile'].first.path #first is an alias for [0] # create a Tempfile reference fromfile = cgi.params['myfile'].first #displays the original file name as supplied in the form puts fromfile.original_filename # displays the content (mime) type e.g. text/html puts fromfile.content_type # create output file reference as original filename in our chosen directory tofile = '/usr/local/www/somwhere/nice/'+fromfile.original_filename # copy the file # note the untaint prevents a security error # cgi sets up an StringIO object if file < 10240 # or a Tempfile object following works for both File.open(tofile.untaint, 'w') { |file| file << fromfile.read} # when the page finishes the Tempfile/StringIO!) thing is deleted automatically # File transfer forms allow multiple files to be selected and uploaded # so better code would be cgi['myfile'].each do |fromfile| tfn = "/user/local/www/somewhere/else/"+fromfile.original_filename File.open(tfn.untaint, 'w') { |file| file << fromfile.read} end </pre> <p>See also some more notes on <a href="#forms" class="t-db">CGI form variables</a>.</p> <p><a href="#contents"><img class="i-u" src="../../../images/go_up.gif" alt="GO UP"></a></p> <h2 id="convert">Type Conversion</h2> <p>The following type conversions may be used:</p> <pre class="g-b-n"> # convert an FixNum to printable format (string) print 1.to_s # => "1" # string to integer print "a".to_i # => 0 print "123".to_i # => 123 print "1a23".to_i # => 1 # integer to float print 1.to_f # => 1.0 # .hex converts from hex to decimal print "a".hex # =>10 </pre> <p><a href="#contents"><img class="i-u" src="../../../images/go_up.gif" alt="GO UP"></a></p> <h2 id="iterate">Iteration and blocks</h2> <p>There are some confusing issues to do with blocks and iterations:</p> <pre class="g-b-n"> # these both work myfile.each {|x| x.grep (/me/){|i| puts i+"<br />"} } myfile.grep (/me/) { |i| puts i+"<br />" } # this does NOT work - which surprised us myfile.grep.each (/me/) { |i| puts i+"<br />" } </pre> <p><a href="#contents"><img class="i-u" src="../../../images/go_up.gif" alt="GO UP"></a></p> <h2 id="dirs">Files and Directories</h2> <p>Some notes about handling files and directories:</p> <pre class="g-b-n"> # anything above $SAFE = 0 you need to untaint everything # directory/file analysis # prints directories in order followed by ordered files to first level dirs = "/usr/local/www"+dir ddirs = Array.new dfiles = Array.new md = Dir.open(dirs.untaint).each do |file| # exclude the crap if file != "." and file != ".." # lstat needs full path if File.lstat(dirs+"/"+file.untaint).directory? ddirs << file else dfiles << file end end end ddirs.sort.each {|x| puts x+"<br />"} dfiles.sort.each {|x| puts x+"<br />"} md.close # or a single liner (Dir.entries(/dir/path/)-[".", ".."]).each {|x| print x} </pre> <p><a href="#contents"><img class="i-u" src="../../../images/go_up.gif" alt="GO UP"></a></p> <h2 id="files">Files Reading 'n writing</h2> <p>Some notes about reading and writing from/to files. Like a lot of folks we like to close files. But ruby can get a little confusing and if its autoclosed then a reference to your file object will throw an exception 'cos is been garbage collected and ..like...its gone man. IO methods don't even open a file so they always close it! Simple rule of thumb. If you handle a file as series of lines there is no autoclose, if you touch it as a file wham its autoclosed see below:</p> <pre class="g-b-n"> # IO versions have auto open/close # read whole file into an array ma = IO.readlines("myfile") # iterator verion (autoclose) IO.foreach("myfile") {|line| do something line} # File treated as lines will not autoclose # NB: open defaults to mode "r" mf = File.open("myfile") # default line separator is $\= RS mf.each_line {|line| do something} # slices up input using "end" separator mf.each_line("end") {|line| do something} mf.close # gotta close it # to append data to file (use 'a' or 'a+') mf = File.open("myfile","a") mf.print(line) mf.close # to add in sequence record - rewrite file ma = IO.readlines("myfile") # do stuff in array mf = File.open("myfile","w") ma.each {|line| mf.print(line)} mf.close # treating as a file (not lines) will autoclose mf = File.open("myfile") do |f| f.readlines.each {|l| print l} end </pre> <p><a href="#contents"><img class="i-u" src="../../../images/go_up.gif" alt="GO UP"></a></p> <h2 id="stuff">Stuff about Objects</h2> <p>So you are stuck, the documentation is either non-existent or you can't find it. You have no idea what to do next. The following code provides some information about the object:</p> <pre class="g-b-n"> # display a list of object methods thing.methods.each {|x| print x+'<br />'} # check for a single method if thing.respond_to?("to_s") then thing.to_s end # test for a particular class if thing.kind_of?("String") then ... # displays objects class print thing.class.to_s # you still see thing.type but we understand # the 'type' method is being deprecated </pre> <p>Seems ruby 1.8 needs the .to_s method to print the class type unlike 1.6.</p> <p><a href="#contents"><img class="i-u" src="../../../images/go_up.gif" alt="GO UP"></a></p> <h2 id="library">Ruby Library and Path Locations</h2> <p>This has gotten significantly more complex with gems and a whole bunch of other stuff:</p> <pre class="g-b-n"> # libary base [FreeBSD] /usr/local/lib/ruby [RedHat] /usr/lib/ruby # assume base for OS above x.x # standard library functions site_ruby/x.x # site specific including rubygems.rb site_ruby/x.x/-i386-freebsdx # architecture specific gems/x.x/cache # .gem files for installed gems gems/x.x/doc # installed rdoc and ri for installed gems (if any) gems/x.x/gems # installed rubygems gems/x.x/specifications # .gemspec files for installed gems </pre> <p>The environmental variable <b>RUBYLIB</b> can also be used to control the location and the GLOBAL $: allows manipulation at run-time e.g.:</p> <pre class="g-c-s"> # adds path/to/my/lib for use in require and load $: < "path/to/my/lib" </pre> <p><a href="#contents"><img class="i-u" src="../../../images/go_up.gif" alt="GO UP"></a></p> <h3 id="each">Implementing an each method in a Class</h3> <p>The following ruby code implements an each method where the underlying object already has an each method:</p> <pre class="g-b-n"> class Thingy def initialize @myarray = Array.new # fill array @myhash = Hash.new # fill hash end def for_each @myarray.each {|x| yield x} end # for_each with hash def for_each @myhash.each {|k,v| yield k,v} end end # usage t = Thingy.new # do stuff # the 'do something is executed for each element # in our array by the 'yield' in each method t.for_each {|x| do something x} # the 'do something is executed for each element # in our hash by the 'yield' in for_each method # accessing both k and v t.for_each {|k,v| do something with k and v} # you could write a each_key method e.g. # t.each_key {|k| do something with k} </pre> <p><a href="#contents"><img class="i-u" src="../../../images/go_up.gif" alt="GO UP"></a></p> <h2 id="resolv">Using Ruby STD-LIB Resolv.rb</h2> <p>Incomplete documentation for using the fiendishly overcomplicated (and incomplete) Resolv.rb Std-Lib function:</p> <p>Simple host name look-up:</p> <pre class="g-b-s"> # returns a string of the IP address print Resolv.getaddress("www.mydomain.com") # => 192.168.0.1 # NB: must be a full host name </pre> <p>Simple reverse look-up:</p> <pre class="g-b-s"> # returns a string print Resolv.getaddress("192.168.0.1") # gives error - to be investigated </pre> <h3>Using the Stub Resolver:</h3> <p>Gets various Resource Records (RR) for the supplied parameter (for <a title="" href="http://www.zytrax.com/books/dns/ch8" class="t-db">description of each RR</a>)</p> <p>To get the base domain records (NS, SOA and MX) use the following:</p> <pre class="g-b-s"> # use only the base domain name # Resolv::DNS::Resource::IN::ANY gets all RR types dns = Resolv::DNS.new dns.getresources("mydomain.com", Resolv::DNS::Resource::IN::ANY).collect do |r| # each record type has different properties - need to test # see property list <a href="#rr-props">below</a> if r.kind_of?(Resolver::DNS::Resource::IN::MX) then # Note: every property nned a .to_s method print r.preference.to_s print r.exchange.to_s elsif etc. ... end end </pre> <p>To get only the SOA record for the domain:</p> <pre class="g-b-s"> # use only the base domain name # Resolv::DNS::Resource::IN::SOA gets only SOA type dns = Resolv::DNS.new dns.getresources("mydomain.com", Resolv::DNS::Resource::IN::SOA).collect do |r| print r.mname # etc end </pre> <p>To get only an A record:</p> <pre class="g-b-s"> # must use the full host name dns = Resolv::DNS.new dns.getresources("ftp.mydomain.com", Resolv::DNS::Resource::IN::A).collect do |r| print r.address # etc end </pre> <h3>Handling Errors</h3> <p><b>Resolve</b> throws an exception for everything that moves and gives you only text which is not exactly useful behaviour:</p> <pre class="g-b-s"> # must use the full host name dns = Resolv::DNS.new begin dns.getresources("ftp.mydomain.com", Resolv::DNS::Resource::IN::A).collect do |r| print r.address # etc end rescue StandardError => ouch print ouch end </pre> <p><a href="#contents"><img class="i-u" src="../../../images/go_up.gif" alt="GO UP"></a></p> <h4 id="rr-props">Resource Record Properties</h4> <p>Following is an incomplete list of RRs and their properties - excludes boring and not very useful records such as TEXT, HINFO, WKS:</p> <pre class="g-b-s"> Each RR record type has differing properties Properties of each record type must use .to_s on ALL records to convert from type e.g. obj.address.to_s MX preference = preference number exchange = domain name of mail exchanger NS name = name server host name A address = ip address SOA mname = primary name server for domain rname = email address (in dot format) serial = serial number of record refresh = refresh period retry = retry expire = expiration of record minimum = timeout PTR name = host name </pre> <p><a href="#contents"><img class="i-u" src="../../../images/go_up.gif" alt="GO UP"></a></p> <h2 id="fileutils">Notes on using FileUtils.rb</h2> <p>We needed to change permissions and ownership on a number of files and directories from ruby. FileUtils (up to 1.8.2) does not hack it - but 1.9 FileUtils provides a number of new methods - particularly chown_R, chmod and chmod_R which we wanted. So... We downloaded a <a title="" href="http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/ruby/lib/fileutils.rb" class="t-db">CVS copy of FileUtils.rb</a> and tried it. It works perfectly. We now have chown_R etc available in our otherwise stock 1.8.2 ruby lib.</p> <p>However we ran into a problem. The particular application we were writing takes a command line argument which defines the mode (permission mask) to be applied to a series of directories created by the application e.g. 0770 type values. So we saved the command line argument in a variable and tried to use the variable in the resulting chmod and ruby choked - badly. All the examples shown explicit values being used. Here is out little journey to a solution in code fragments:</p> <pre class="g-b-s"> # all the class examples use explicit mask values like this - which works FileUtils.chmod_R(0774,directory) # when a variable is used ruby chokes - it wants a fixnum mask = "0774" directory = "/var/new/some-directory" FileUtils.chmod_R(mask,directory) # OK so this really stupid but we wanted to see the result mask = 0774 directory = "/var/new/some-directory" FileUtils.chmod_R(mask,directory) # worked but with wild mask results as expected # when in doubt use eval so we used this - and it works mask = "0774" directory = "/var/new/some-directory" # messy escaping required ts = "FileUtils.chmod_R("+mask+',"'+directory+'")' eval(ts) </pre> <p><a href="#contents"><img class="i-u" src="../../../images/go_up.gif" alt="GO UP"></a></p> <h2 id="multi-hash">Multi-Level Hashes</h2> <p>We use a lot of multi-level hashes to reflect complex record structures. Here are some notes that may help you:</p> <pre class="g-b-s"> # ruby chokes on this h = Hash.new # or {} h[0][0][0] = "one" # gives 'nil' error # this works h = Hash.new # or {} h[0] = {} h[0][0] = {} h[0][0][0] = "one" # or h = Hash.new # or {} h[0] = {0=>{0=>"one"}} # generic rule seems to be add one level at a time on left </pre> <p><a href="#contents"><img class="i-u" src="../../../images/go_up.gif" alt="GO UP"></a></p> <h2 id="multi-return">Returning Multiple Values</h2> <p>There is no end to the magic of ruby - or more probably we've had too many years with single return procedural languages - OK so you can return structures. Well we're talking ruby now - so forget all that stuff. You can return as many comma separated values as you want with ruby, see examples below:</p> <pre class="g-b-s"> # simple in-line function with multiple return values def multi_return(one) return one+1, one+2, one+3 end # appears that the above actually returns an array # e.g. [2,3,4] which can then be assigned or ignored # assigns all returns two, three, four = multi_return(one) # assigns first two returns - ignore third two,three = multi_return(one) # by-the-way you can omit return if # the thing you want to return is the last result # this works as expected and returns true or false class Test def Test.test_it(num) num > 20 end end if Test.test_it(25) then # do something end </pre> <p><a href="#contents"><img class="i-u" src="../../../images/go_up.gif" alt="GO UP"></a></p> <h2 id="exceptions">Errors and Exceptions</h2> <p>We found this very confusing for a long time - still do actually! Here is our explanation - if we are wrong let us know...</p> <p>The main error object is class <b>Exception</b>, a number of subclasses seem to have been defined - some of which have additional methods or attributes but many don't. The reason they seem to have been created is to <b>classify</b> errors and to allow you to handle, via <b>rescue</b>, specific errors.</p> <pre class="g-c-s"> Currently avaialable errortypes (subclasses of Exception) Those marked with * have additional methods ArgumentError - IndexError Interrupt LoadError NameError * (name, new, to_s) NoMemoryError NoMethodError * (args, new) NotImplementedError RangeError RuntimeError ScriptError SecurityError SignalException StandardError SyntaxError SystemCallError * (===, errno, new) SystemExit * {new, status) TypeError fatal </pre> <h4>Methods</h4> <p>The following is an incomplete list of methods. <a title="" href="http://www.ruby-doc.org/" target="_blank" class="t-db">See also Core-API</a>. <pre class="g-c-s"> # backtrace method #================= # the most useful returns array of strings # usage ======= # all errors types begin ... rescue =>oof oof.backtrace.each {|x| print x} end # OR # specific error begin ... rescue StandardError =>oof oof.backtrace.each {|x| print x} end </pre> <h4>Roll-your-own</h4> <p>You can make your own error objects to create new methods or provide additional information.</p> <pre class="g-c-s"> class Someclass def sm begin ... buggy code ... rescue StandardError =>oops my Myerror.new("ouch") my.number(15) raise my end class Myerror < StandardError attr_reader :num def initialize do something end def number(num) @num = num end end end end # use m = Someclass.new begin m.sm rescue Myerror =>oof print oof.num.to_s end </pre> <p><a href="#contents"><img class="i-u" src="../../../images/go_up.gif" alt="GO UP"></a></p> <hr> <p class="p-m-n"><br>Problems, comments, suggestions, corrections (including broken links) or something to add? Please take the time from a busy life to 'mail us' (at top of screen), the webmaster (below) or <a href="javascript:mailus('info-support','zytrax.com','Support Issue')" class="t-db">info-support at zytrax</a>. You will have a warm inner glow for the rest of the day.</p> <!-- end body div l-c --> </div> <div class="l-l"> <!-- left hand navigation --> <div class="n-l"> <p class="c-g t-b t-o m-h5 t-r">Tech Stuff</p> <!-- first row of navigation CSS format --> <ul class="n-l1p"> <li class="n-l1p-e"> <a href="http://www.zytrax.com/tech" class="n-l-c">tech home</a> </li> </ul> <ul class="n-l1p"> <li class="n-l1p-e"> <a title="Digital Audio - primers, calculators, equalization, frequency tables, file formats, glossary - a mere splash in the ocean" href="http://www.zytrax.com/tech/audio/" class="n-l-c">audio stuff</a> <ul class="n-l2"> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/audio/sound.html" class="n-l-f">sound primer</a></li> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/audio/digital-sound.html" class="n-l-f">digital primer</a></li> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/audio/audio.html" class="n-l-f">note frequencies</a></li> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/audio/equalization.html" class="n-l-f">eq, meters & fft</a></li> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/audio/calculator.html" class="n-l-f">calculators</a></li> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/audio/formats.html" class="n-l-f">files & codecs</a></li> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/audio/glossary.html" class="n-l-f">glossary</a></li> </ul> </li> </ul> <ul class="n-l1p"> <li class="n-l1p-e"> <a title="Browser IDs, SSIs, Apache Configuration, regular expressions" href="http://www.zytrax.com/tech/web/" class="n-l-c">web stuff</a> <ul class="n-l2"> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/web/browser_ids.htm" class="n-l-f">browser ids</a></li> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/web/mobile_ids.html" class="n-l-f">mobile_ids</a></li> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/web/env_var.htm" class="n-l-f">apache env vars</a></li> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/web/ssi.htm" class="n-l-f">apache ssi</a></li> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/css/workarounds.html#popout" class="n-l-f">css popout menus</a></li> <li class="n-l2-e"><a title="most of those annoying HTML entity codes that we forget all the time" href="http://www.zytrax.com/tech/web/entities.html" class="n-l-f">html entities</a></li> <li class="n-l2-e"><a title="Decimal to Hexidecimal to Binary conversion - even Octal!" href="http://www.zytrax.com/tech/protocols/hex.html" class="n-l-f">dec > hex > bin</a></li> </ul> </li> </ul> <ul class="n-l1p"> <li class="n-l1p-e"> <a href="http://www.zytrax.com/tech/dom/" class="n-l-c">dom stuff</a><br> <ul class="n-l2"> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/dom/guide.html" class="n-l-f">dom guide</a></li> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/dom/w3c_dom.html" class="n-l-f">page explorer</a></li> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/dom/navigate.html" class="n-l-f">dom navigation</a></li> </ul> </li> </ul> <ul class="n-l1p"> <li class="n-l1p-e"> <a title="CSS is about a lot more than STYLE. Wheezes, table-less layouts, CSS pop-ups, CSS Shortcuts" href="http://www.zytrax.com/tech/css/" class="n-l-c">css stuff</a> <ul class="n-l2"> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/css/layoutnotes.html" class="n-l-f">css liquid design</a></li> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/css/workarounds.html#popout" class="n-l-f">css popout menus</a></li> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/css/workarounds.html" class="n-l-f">css notes</a></li> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/css/syntax.html" class="n-l-f">css syntax</a></li> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/css/shortcut.html" class="n-l-f">css short-forms</a></li> </ul> </li> </ul> <ul class="n-l1p"> <li class="n-l1p-e"> <a title="includes PHP, Ruby and some Java stuff (all about obscure solutions to stupid problems)" href="http://www.zytrax.com/tech/lang/" class="n-l-c">language stuff</a> </li> </ul> <ul class="n-l1p"> <li class="n-l1p-e"> <a title="quick overview 'cos we always forget - not that we ever knew much - now includes a nifty browser-based tester" href="http://www.zytrax.com/tech/web/regex.htm" class="n-l-c">regex stuff</a> </li> </ul> <ul class="n-l1p"> <li class="n-l1p-e"> <a title="rfc ordered by subject" href="http://www.zytrax.com/tech/rfcs/" class="n-l-c">rfc stuff</a> <ul class="n-l2"> <li title="dns rfcs" class="n-l2-e"><a href="http://www.zytrax.com/books/dns/apd/" class="n-l-f">dns rfcs</a></li> <li title="ldap rfcs" class="n-l2-e"><a href="http://www.zytrax.com/books/ldap/apc/" class="n-l-f">ldap rfcs</a></li> <li title="ipv6 rfcs" class="n-l2-e"><a href="http://www.zytrax.com/tech/protocols/ipv6.html#rfcs" class="n-l-f">ipv6 rfcs</a></li> <li title="tls/x.509 rfcs" class="n-l2-e"><a href="http://www.zytrax.com/tech/survival/ssl.html#rfcs" class="n-l-f">tls/x.509 rfcs</a></li> <li title="some other subjects - we only update these when we are active - some lists are consequently long in the tooth" class="n-l2-e"><a href="http://www.zytrax.com/tech/rfcs" class="n-l-f">other rfcs</a></li> </ul> </li> </ul> <ul class="n-l1p"> <li class="n-l1p-e"> <a title="TCP/IP, IPv4, IPv6, ISDN, LAN, VoIP, ITU Multi-Media" href="http://www.zytrax.com/tech/protocols/" class="n-l-c">protocol stuff</a> <ul class="n-l2"> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/protocols/tcp.html" class="n-l-f">tcp, udp, icmp</a></li> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/protocols/ip-classes.html" class="n-l-f">ipv4</a></li> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/protocols/ipv6.html" class="n-l-f">ipv6</a></li> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/protocols/isdn/" class="n-l-f">isdn</a></li> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/survival/ssl.html" class="n-l-f">ssl/tls/x.509</a></li> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/ss7/" class="n-l-f">ss7 &sigtran</a></li> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/protocols/lan/" class="n-l-f">802.3 lan</a></li> </ul> </li> </ul> <ul class="n-l1p"> <li class="n-l1p-e"> <a title="PC Parallel Ports, LAN wiring, RS232, Centronics, DIN" href="http://www.zytrax.com/tech/layer_1/" class="n-l-c">cable stuff</a> <ul class="n-l2"> <li title="10baseT, 100base-TX/T4, 1000baseT, 10Gbase-T, RJ45, STP" class="n-l2-e"><a href="http://www.zytrax.com/tech/layer_1/cables/tech_lan.htm" class="n-l-f">lan pinouts</a></li> <li title="mixing telephony and 802.3 LAN can be done on cat5/5e/6 wiring" class="n-l2-e"><a href="http://www.zytrax.com/tech/layer_1/mixed.html" class="n-l-f">lan & telephone</a></li> <li title="RS 232 pinouts on db9, db24 and T1" class="n-l2-e"><a href="http://www.zytrax.com/tech/layer_1/cables/tech_rs232.htm" class="n-l-f">rs232 pinouts</a></li> <li class="n-l2-e"><a href="http://www.zytrax.com/tech/layer_1/cables/heavy.htm" class="n-l-f">serial primer</a></li> <li title="USB 2.0, 3.0, 3.1 and 3.2 plus Firewire (i.Link) IEE 1394" class="n-l2-e"><a href="http://www.zytrax.com/tech/pc/serial.html" class="n-l-f">usb & firewire</a></li> <li title="some information about display and monitors/console interfaces inclusing VGA, HDMI, DVI and Thunderbolt" class="n-l2-e"><a href="http://www.zytrax.com/tech/pc/monitors.htm" class="n-l-f">displays</a></li> <li title="modular jack is the term we should use for those telephone and lan connectors" class="n-l2-e"><a href="http://www.zytrax.com/tech/layer_1/cables/cables_jacks.htm" class="n-l-f">modular jacks</a></li> </ul> </li> </ul> <ul class="n-l1p"> <li class="n-l1p-e"> <a title="10baseT, 100base-TX/T4, 1000baseT, 10Gbase-T, RJ45, STP" href="http://www.zytrax.com/tech/layer_1/cables/tech_lan.htm" class="n-l-c">lan wiring</a> </li> </ul> <ul class="n-l1p"> <li class="n-l1p-e"> <a title="DB9, DB25 pinouts, RJ45 serial, T1 and RS standards alphabet soup" href="http://www.zytrax.com/tech/layer_1/cables/tech_rs232.htm" class="n-l-c">rs232 wiring</a> </li> </ul> <ul class="n-l1p"> <li class="n-l1p-e"> <a title="Decimal to Hex and Binary conversion table - even a description of Octal!" href="http://www.zytrax.com/tech/protocols/hex.html" class="n-l-c">dec > hex > bin</a> </li> </ul> <ul class="n-l1p"> <li class="n-l1p-e"> <a title="character sets ain't as simple as they look" href="http://www.zytrax.com/tech/codes.htm" class="n-l-c">character sets</a> <ul class="n-l2"> <li title="pretty much all the characters sets in the known universe including utf-7, 8 and 16" class="n-l2-e"><a href="http://www.zytrax.com/tech/characters/" class="n-l-f">character sets</a></li> <li title="ascii variant of international reference alphabet 5 (ira5)" class="n-l2-e"><a href="http://www.zytrax.com/tech/codes.htm" class="n-l-f">ascii codes</a></li> <li title="international reference alphabet 5 (ascii's cousin)" class="n-l2-e"><a href="http://www.zytrax.com/tech/ia5.html" class="n-l-f">ia5 codes</a></li> <li title="all that ™ & © stuff" class="n-l2-e"><a href="http://www.zytrax.com/tech/web/entities.html" class="n-l-f">html entities</a></li> <li title="silly page containing a bunch of fonts in various sizes including your PCs defaults" class="n-l2-e"><a href="http://www.zytrax.com/tech/web/fonts.html" class="n-l-f">web fonts</a></li> </ul> </li> </ul> <ul class="n-l1p"> <li class="n-l1p-e"> <a title="The T series, E series and J series and then all that optical stuff (OC-12 etc.)" href="http://www.zytrax.com/tech/data_rates.htm" class="n-l-c">data rate stuff</a> </li> </ul> <ul class="n-l1p"> <li class="n-l1p-e"> <a title="Even us electronic guys gotta know how to screw it together, if you get our drift" href="http://www.zytrax.com/tech/mech/" class="n-l-c">mechanical stuff</a> <ul class="n-l2"> <li title="fastener (screw) head styles - surprising number of choices" class="n-l2-e"><a href="http://www.zytrax.com/tech/mech/heads.htm" class="n-l-f">head styles</a></li> <li title="threads for imperial (UNF, UNC) & metric sizes" class="n-l2-e"><a href="http://www.zytrax.com/tech/mech/threads.htm" class="n-l-f">threads</a></li> </ul> </li> </ul> <ul class="n-l1p"> <li class="n-l1p-e"> <a title="A collection of howtos including Samba3 as PDC, FreeBSD firewalls" href="http://www.zytrax.com/tech/howtos/" class="n-l-c">howto stuff</a> </li> </ul> <ul class="n-l1p"> <li class="n-l1p-e"> <a title="A collection of survival guides - quick overviews - to popular software" href="http://www.zytrax.com/tech/survival/" class="n-l-c">survival stuff</a> <ul class="n-l2"> <li title="tls and x.509 (ssl) certificates - warning: headache inducing stuff" class="n-l2-e"><a href="http://www.zytrax.com/tech/survival/ssl.html" class="n-l-f">ssl/tls/x.509</a></li> <li title="Abstract Syntax Notation. 1 (ASN.!) and Distinguished Encoding Rules (DER) - not for the faint hearted. Pass the pain medication, we feel a headache coming on." class="n-l2-e"><a href="http://www.zytrax.com/tech/survival/asn1.html" class="n-l-f">ASN.1 & DER</a></li> <li title="Kerberos is great - but tough, oh my, tough stuff" class="n-l2-e"><a href="http://www.zytrax.com/tech/survival/kerberos.html" class="n-l-f">kerberos</a></li> <li title="We've used postfix for years but always forget which of the 27 million parameters to use" class="n-l2-e"><a href="http://www.zytrax.com/tech/survival/postfix.html" class="n-l-f">postfix</a></li> <li title="Symetric, asymetric, MACs, hashes - eye watering stuff" class="n-l2-e"><a href="http://www.zytrax.com/tech/survival/encryption.html" class="n-l-f">encryption</a></li> <li title="Just what time is it in Kuala Lumpur, and what's that got to do with cron?" class="n-l2-e"><a href="http://www.zytrax.com/tech/survival/cron.html" class="t-db">cron</a></li> <li title="Gotta love wxWidgets - free, fantastic, flexible - but hard to see the wood for the trees sometimes" class="n-l2-e"><a href="http://www.zytrax.com/tech/survival/wxwidgets.html" class="n-l-f">wxWidgets</a></li> </ul> </li> </ul> <ul class="n-l1p"> <li class="n-l1p-e"> <a title="Our wireless overview, Calculators, Fresnel zones, links to 'heavy' stuff, some early 802.11 stuff (mostly wi-fi related)" href="http://www.zytrax.com/tech/wireless/" class="n-l-c">wireless stuff</a> <ul class="n-l2"> <li title="our irreverent general intro to wirelss - purist will not like this page" class="n-l2-e"><a href="http://www.zytrax.com/tech/wireless/intro.htm" class="n-l-f">overview</a></li> <li title="wireless calculators for system budgets, free-space loss, fresnel effects and a bunch of other stuff" class="n-l2-e"><a href="http://www.zytrax.com/tech/wireless/calc.htm" class="n-l-f">calculators</a></li> <li title="fresnel effect explanation - well, we can understand it" class="n-l2-e"><a href="http://www.zytrax.com/tech/wireless/fresnel.htm" class="n-l-f">fresnel effects</a></li> <li title="our outrageously biased description of frequency hopping versus direct sequence for spread spectrum" class="n-l2-e"><a href="http://www.zytrax.com/tech/wireless/fh_ds.htm" class="n-l-f">fh vs ds</a></li> <li title="some terminology covering 802 standards and modulation techniques" class="n-l2-e"><a href="http://www.zytrax.com/tech/wireless/soup.html" class="n-l-f">wireless soup</a></li> </ul> </li> </ul> <ul class="n-l1p"> <li class="n-l1p-e"> <a title="Pinouts - USB, DIN, Firewire, VGA, DVI, HDMI, DisplayPort and Thunderbolt, I/O interface speeds, Screen sizes including HD" href="http://www.zytrax.com/tech/pc/" class="n-l-c">pc stuff</a> <ul class="n-l2"> <li title="din and mini-din for older PCs" class="n-l2-e"><a href="http://www.zytrax.com/tech/pc/din.htm" class="n-l-f">din & mini-din</a></li> <li title="802.3 LAN stuff" class="n-l2-e"><a href="http://www.zytrax.com/tech/layer_1/cables/tech_lan.htm" class="n-l-f">802.3 lan</a></li> <li title="connection of monitors has changed over the years from clunky VGA to svelte HDMI - all the pinouts you could hope for" class="n-l2-e"><a href="http://www.zytrax.com/tech/pc/monitors.htm" class="n-l-f">monitor pinouts</a></li> <li title="serial (db9, db24) connections - slow but trusty" class="n-l2-e"><a href="http://www.zytrax.com/tech/layer_1/cables/tech_rs232.htm" class="n-l-f">serial stuff</a></li> <li title="usb pinouts and descriptions of power levels for usb 1, 2 and 3 - also includes firewire" class="n-l2-e"><a href="http://www.zytrax.com/tech/pc/serial.html" class="n-l-f">usb & firewire</a></li> <li title="pc interfaces are changing and getting faster - we can never keep up - list of interfaces and their speeds" class="n-l2-e"><a href="http://www.zytrax.com/tech/pc/interfaces.html" class="n-l-f">pc interfaces</a></li> <li title="we get confused about most things - just what is 1080p - pc and tv screen resolution table with some explanations" class="n-l2-e"><a href="http://www.zytrax.com/tech/pc/resolution.html" class="n-l-f">screen resolutions</a></li> </ul> </li> </ul> <ul class="n-l1p"> <li class="n-l1p-e"> <a title="Electronic glossary, some old experiments with 3.3/5V protection and early BGA designs" href="http://www.zytrax.com/tech/electronics/" class="n-l-c">electronic stuff</a> </li> </ul> <ul class="n-l1p"> <li class="n-l1p-e"> <a title="ragbag collection of links that we publish from time to time - maybe useful, maybe not" href="http://www.zytrax.com/links" class="n-l-c">tech links</a> </li> </ul> <ul class="n-l1p"> <li class="n-l1p-e"> <a title="Our DNS and LDAP for Rocket Scientists guides" href="http://www.zytrax.com/books" class="n-l-c">open guides</a> <ul class="n-l2"> <li title="dns for rocket scientists" class="n-l2-e"><a href="http://www.zytrax.com/books/dns/" class="n-l-f">dns guide</a></li> <li title="ldap for rocket scientists" class="n-l2-e"><a href="http://www.zytrax.com/books/ldap/" class="n-l-f">ldap guide</a></li> </ul> </li> </ul> <p class="t-r"> <a title="RSS (2.0) Feed - right click on icon, select 'Copy Link URL' or 'Copy Shortcut', paste into RSS Feed Reader, or drag and drop into RSS Feed Reader" href="http://www.zytrax.com/zytrax.rss" class="n-l-c"><img class="w-32 center" src="http://www.zytrax.com/images/rss.png" alt="RSS Feed Icon"></a> </p> <p class="p-b-h t-r">If you are happy it's OK - but your browser is giving a less than optimal experience on our site. You could, at no charge, upgrade to a W3C standards compliant browser such as <a href="http://www.mozilla.org" class="t-db">Firefox</a></p> </div> </div> <div class="l-r"> <!-- right menu --> <div class="w-150"> <!-- SiteSearch Google --> <p class="c-g t-b t-o m-h8">Search</p> <form class="f-b-n" method="get" action="http://www.google.com/custom" target="_top"> <table> <tr> <td style="white-space: nowrap"> <input type="hidden" name="domains" value="www.zytrax.com"> <input class="b-lg" type="text" name="q" size="16" maxlength="255" value=""> </td></tr> <tr> <td style="white-space: nowrap"> <table> <tr> <td> <input type="radio" name="sitesearch" value="" checked="checked"><span class="t-s">web</span> </td> <td> <input type="radio" name="sitesearch" value="www.zytrax.com" ><span class="t-s">zytrax.com</span> </td> </tr> </table> <input class="b-lg" type="submit" name="sa" value="Google Search"> <input type="hidden" name="client" value="pub-9419480011552853"> <input type="hidden" name="forid" value="1"> <input type="hidden" name="ie" value="ISO-8859-1"> <input type="hidden" name="oe" value="ISO-8859-1"> <input type="hidden" name="safe" value="active"> <input type="hidden" name="cof" value="GALT:#008000;GL:1;DIV:#336699;VLC:663399;AH:center;BGC:FFFFFF;LBGC:336699;ALC:0000FF;LC:0000FF;T:000000;GFNT:0000FF;GIMP:0000FF;LH:50;LW:355;L:http://www.zytrax.com/images/zytrax-info-google.gif;S:http://www.zytrax.com/tech;FORID:1;"> <input type="hidden" name="hl" value="en"> </td></tr></table> </form> <!-- SiteSearch Google --> <!-- share page feature --> <div class="t-h"><p><span class="t-g">Share</span></p> <div class="t-h-1"> Icons made by <a href="https://www.flaticon.com/authors/icomoon" title="Icomoon">Icomoon</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> is licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a></div></div> <a href="http://www.facebook.com/share.php?u=http://www.zytrax.com/tech/lang/ruby/&h=Tech%20Stuff%20-%20Ruby"><img class="w-32" title="add page to facebook" src="http://www.zytrax.com/images/facebook.png" alt="share page via facebook"></a> <a href="http://twitter.com/home/?status=Useful%20page%20http://www.zytrax.com/tech/lang/ruby/"><img class="w-32" title="tweet this page" src="http://www.zytrax.com/images/twitter.png" alt="tweet this page"></a> <p class="c-g t-b t-o m-h5">Page<p> <a class="a-n" href="http://www.zytrax.com/feedback.htm"><img class="w-32" title="Page comment feature" src="http://www.zytrax.com/images/mail.png" alt="email us"></a> <a class="a-n" href="http://www.zytrax.com/run/mailpage.php"><img class="w-32" title="Send to a friend" src="http://www.zytrax.com/images/mailfriend.png" alt="Send to a friend feature"></a> <a class="a-n" href="#" onclick="window.print();return false;"><img class="w-32" title="print page" src="http://www.zytrax.com/images/printpage.png" alt="print this page"></a> <a class="a-n" title="View page full width - suppresses left and right hand menus" href="http://www.zytrax.com/tech/lang/ruby/?pf=yes"><img class="w-32" src="http://www.zytrax.com/images/fullwidth.png" alt="Display full width page"></a> <a class="a-n" href="#" onclick="fontchange('d');return false;"><img class="w-32" title="Decrease font size" src="http://www.zytrax.com/images/smaller.png" alt="Decrease font size"></a> <a class="a-n" href="#" onclick="fontchange('i');return false;"><img class="w-32" title="Increase font size" src="http://www.zytrax.com/images/bigger.png" alt="Increase font size"></a> <p class="c-g t-b t-o m-h5">Resources</p> <p> <a title="Home of the language and the RAA - Ruby Application Archive don't confuse it with somewhere to get some simple scripts - Matz hangs out here" href="http://www.ruby-lang.org/en" target="_blank" class="w-db">Main Ruby site</a><br> <a title="The First edition of Pragmatic Programmers Guide - wtitten by Dave Thomas and Andy Hunt who rescued us feeble westerners from ignorance of Ruby" href="http://ruby-doc.com/docs/ProgrammingRuby/" target="_blank" class="w-db">The Book</a><br> <a title="ruby documentation" href="http://www.ruby-doc.org" target="_blank" class="w-db">ruby-doc.org</a><br> <a title="The home of RubyGems" href="http://rubygems.org/" target="_blank" class="w-db">RubyGems</a><br> <a title="The home of Ruby on Rails" href="http://www.rubyonrails.org/" target="_blank" class="w-db">Ruby on Rails</a><br> </p> <p class="c-g t-b t-o m-h5">Useful Stuff</p> <p> <a title="Partially complete Perl Cookbook equivalent in a number of languages including Ruby" href="http://pleac.sourceforge.net/pleac_ruby/t1.html" target="_blank" class="w-db">Ruby PLEAC</a> </p> <p class="c-g t-b t-o m-h5">Our Pages</p> <p> <a title="Some random notes about Ruby and its associated objects and libraries" href="http://www.zytrax.com/tech/lang/ruby/" >our ruby pages</a><br> <a title="The beginning of our alpahabetic point and click glossary to quickly find your way round the language" href="http://www.zytrax.com/tech/lang/ruby/glossary.html" >glossary</a> </p> </div> <p class="c-g t-b t-o">Site</p> <a class="a-n" href="http://www.zytrax.com/about_site.htm#css"><img class="w-32" src="http://www.zytrax.com/images/css.png" alt="CSS Technology"></a> <a class="a-n" href="http://www.zytrax.com/security/spf.html"><img title="SPF Record Conformant Domain" class="w-32" src="http://www.zytrax.com/images/spf.png" alt="SPF Record Conformant Domain"></a> </div> <div class="l-f"> <!-- standard footer full width --> <table> <tr> <td class="p-f-s t-l"> Copyright © 1994 - 2024 ZyTrax, Inc.<br> All rights reserved. <a href="http://www.zytrax.com/legal.html" class="p-f-s">Legal</a> and <a href="http://www.zytrax.com/privacy.html" class="p-f-s">Privacy</a> </td> <td class="t-c"><a href="https://www.zytrax.com" target="_blank" class="p-f-s">site by zytrax</a><br> <a href="https://www.javapipe.com" target="_blank" class="p-f-s">hosted by javapipe.com</a></td> <td class="p-f-s t-r"> <a href="javascript:mailus('web-master','zytrax.com','About Web site')" class="p-f-s">web-master at zytrax</a><br> Page modified: January 20 2022. </td> </tr> </table> </div> <!-- pop-out tables only if Javascript supported --> <!-- only css menus --> </body> </html>