Jimmy SchementiJimmy Schementi's websitehttp://jimmy.schementi.com
47.61487-122.345784Get Your Infrastructure Right<style>
.post {
position: relative;
/*font-weight: 300;
font-family: "Helvetica Neue", Helvetica, sans-serif;*/
}
.brooklynjs-box {
border: 4px solid #222;
background: #222;
color: #fff;
}
.brooklynjs-box-caption {
width: 500px;
margin: 0px auto;
margin-top: 2em;
}
.brooklynjs-box p {
color: #eee;
font-size: 17px;
line-height: 1.5em;
}
.brooklynjs-box a {
color: #fff;
text-decoration: none;
font-weight: bold;
}
.brooklynjs-box a:hover {
text-decoration: underline;
}
.brooklynjs-logo-box {
font-size: 20px;
font-weight: 300;
font-family: "Helvetica Neue", Helvetica, sans-serif;
letter-spacing: .015em;
}
.brooklynjs-logo {
width: 500px;
margin: 20px auto;
font-weight: bold;
font-size: 72px;
text-align: left;
border-top: 4px solid #fff;
line-height: 68px;
position: relative;
}
.brooklynjs-logo .j {
right: 80px;
}
.brooklynjs-logo .s {
right: 0;
}
.brooklynjs-logo span {
position: absolute;
top: 7px;
height: 72px;
width: 72px;
border-radius: 50%;
line-height: 72px;
font-size: 60px;
text-align: center;
background: #f7df1e;
color: #222;
}
img[title="Heroku"],
img[title="Docker"],
img[title="Amazon Web Services"],
img[title="Digital Ocean"] {
margin-bottom: -15px;
margin-top: 15px;
}
img[title="Heroku"] {
height: 5em;
}
img[title="Docker"],
img[title="Amazon Web Services"]{
height: 7em;
}
img[title="Digital Ocean"] {
height: 8em;
}
span.center {
display: block;
text-align: center;
padding: 1em;
}
a[title="Fuck you!"] {
color: inherit;
text-decoration: inherit;
}
a[title="Fuck you!"]:hover {
color: inherit;
text-decoration: underline;
}
</style>
<style>
/*! normalize.css v3.0.0 | MIT License | git.io/normalize */
.slide-style article,.slide-style aside,.slide-style details,.slide-style figcaption,.slide-style figure,.slide-style footer,.slide-style header,.slide-style hgroup,.slide-style main,.slide-style nav,.slide-style section,.slide-style summary{display:block}
.slide-style audio,.slide-style canvas,.slide-style progress,.slide-style video{display:inline-block;vertical-align:baseline}
.slide-style audio:not([controls]){display:none;height:0}
.slide-style [hidden],.slide-style template{display:none}
.slide-style a{background:0 0}
.slide-style a:active,.slide-style a:hover{outline:0}
.slide-style abbr[title]{border-bottom:1px dotted}
.slide-style b{font-weight:700}
.slide-style dfn{font-style:italic}
.slide-style h1{font-size:2em}
.slide-style mark{background:#ff0;color:#000}
.slide-style small{font-size:80%}sub,.slide-style sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}.slide-style sup{top:-.5em}.slide-style sub{bottom:-.25em}.slide-style img{border:0}
.slide-style svg:not(:root){overflow:hidden}
.slide-style figure{margin:1em 40px}
.slide-style hr{box-sizing:content-box}
.slide-style pre{overflow:auto}
.slide-style code,.slide-style kbd,.slide-style pre,.slide-style samp{font-size:1em}
.slide-style kbd,.slide-style pre,.slide-style samp{font-family:monospace, monospace}
.slide-style button,.slide-style input,.slide-style optgroup,.slide-style select,.slide-style textarea{color:inherit;font:inherit;margin:0}
.slide-style button{overflow:visible}
.slide-style button,.slide-style select{text-transform:none}
.slide-style button,.slide-style input[type="button"],.slide-style input[type="reset"],.slide-style input[type="submit"]{-webkit-appearance:button;cursor:pointer}
.slide-style button[disabled],.slide-style input[disabled]{cursor:default}
.slide-style button::-moz-focus-inner,.slide-style input::-moz-focus-inner{border:0;padding:0}
.slide-style input{line-height:normal}
.slide-style input[type="checkbox"],.slide-style input[type="radio"]{box-sizing:border-box;padding:0}
.slide-style input[type="number"]::-webkit-inner-spin-button,.slide-style input[type="number"]::-webkit-outer-spin-button{height:auto}
.slide-style input[type="search"]{-webkit-appearance:textfield;box-sizing:content-box}
.slide-style input[type="search"]::-webkit-search-cancel-button,.slide-style input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}
.slide-style fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
.slide-style legend{border:0;padding:0}
.slide-style textarea{overflow:auto}
.slide-style optgroup{font-weight:700}
.slide-style table{border-collapse:collapse;border-spacing:0}
.slide-style td,.slide-style th,.slide-style *{padding:0}
.slide-style *{margin:0}
.slide-style .bespoke-parent{font-size:1.5em;background:#111;color:#ddd;font-family:futura, helvetica, arial, arial, sans-serif;overflow:hidden;text-align:center;-webkit-transition:background 1s ease;transition:background 1s ease;background-position:50% 50%}
/*.slide-style .bespoke-parent,.slide-style .bespoke-scale-parent{position:absolute;top:0;left:0;right:0;bottom:0}*/
.slide-style .bespoke-parent,.slide-style .bespoke-scale-parent{position:relative}
.slide-style .bespoke-parent h2, .slide-style .bespoke-parent h3 { color: #ddd; }
.slide-style .bespoke-scale-parent{pointer-events:none;z-index:1}
.slide-style .bespoke-scale-parent .bespoke-active{pointer-events:auto}
.slide-style .bespoke-slide{-webkit-transition:opacity .5s ease;transition:opacity .5s ease;/*width:940px;height:480px;position:absolute;top:50%;left:50%;margin-left:-470px;margin-top:-240px;*/display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;z-index:1}
.slide-style .bespoke-active{-webkit-transition-delay:.5s;transition-delay:.5s}
.slide-style .bespoke-active[data-bespoke-backdrop]{-webkit-transition-delay:.75s;transition-delay:.75s}
.slide-style .bespoke-inactive{opacity:0;pointer-events:none}
.slide-style .bespoke-backdrop{-webkit-transition:opacity 1s ease;position:absolute;top:0;left:0;right:0;bottom:0}
.slide-style .bespoke-progress-parent{position:absolute;top:0;left:0;right:0;height:.3vw;z-index:1}
.slide-style .bespoke-progress-bar{background:#ddd;position:absolute;top:0;left:0;height:100%;-webkit-transition:width 1s ease;transition:width 1s ease}
.slide-style .bespoke-bullet{-webkit-transition:opacity .3s ease;transition:opacity .3s ease}
.slide-style .bespoke-bullet-inactive{opacity:0}
.slide-style strong{font-weight:400}
.slide-style hr{width:50%;margin:1rem auto;height:1px;border:0;background:#ddd}
.slide-style h3,.slide-style p,.slide-style li{padding-left:20px;padding-right:20px}
.slide-style h3,.slide-style h4,.slide-style p,.slide-style li,.slide-style pre{font-weight:200}
.slide-style h1{line-height:1.4em;padding:1em;border:1px solid #ddd;border-left-width:0;border-right-width:0;min-width:8em}
.slide-style h1,.slide-style h2{letter-spacing:.3em;text-transform:uppercase;font-weight:400;margin:.17em 0;position:relative}
.slide-style h2{line-height:1.1em;padding:0 0 0 .3em}
.slide-style h3{font-family:didot, times new roman, serif;font-style:italic;font-size:1.2em;line-height:1.6em;margin:.5em 0}
.slide-style h4{text-transform:uppercase;font-size:.8em;line-height:1.8em;letter-spacing:.3em;margin:1em 0}
.slide-style ul,.slide-style ol{padding:0;margin:0;text-align:left}
.slide-style li{list-style:none;margin:.2em;font-style:normal;-webkit-transform:translateX(-6px);-ms-transform:translateX(-6px);transform:translateX(-6px)}
.slide-style li:before{content:'\2014';margin-right:4px}
.slide-style pre{background:none!important}
.slide-style code{font-family:prestige elite std, consolas, courier new, monospace!important;font-style:normal;font-weight:200!important;text-align:left}
.slide-style a{padding-left:.3em;color:currentColor;text-decoration:none;border-bottom:1px solid currentColor}
.slide-style .emphatic{background:rgb(255, 51, 0);}
.slide-style .single-words{word-spacing:9999px;line-height:2.9em;overflow:hidden}
.slide-style .bespoke-backdrop{opacity:0;-webkit-transition:opacity 1s ease,.slide-style -webkit-transform 6s ease;transition:opacity 1s ease,.slide-style transform 6s ease;background-size:cover;background-position:50% 50%;-webkit-transform:translateZ(0)scale(1.3);transform:translateZ(0)scale(1.3)}
.slide-style .bespoke-backdrop-active,.slide-style .bespoke-backdrop-before{-webkit-transform:translateZ(0);transform:translateZ(0)}
.slide-style .bespoke-backdrop-before{-webkit-transition-delay:.2s;transition-delay:.2s}
.slide-style .bespoke-backdrop-active{opacity:.5}
</style>
<style>
.slide-style code[class*="language-"],.slide-style pre[class*="language-"] {
color: #f8f8f2;
text-shadow: 0 1px rgba(0,0,0,.3);
font-family: Consolas,Monaco,'Andale Mono',monospace;
direction: ltr;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
line-height: 1.5;
-moz-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none
}
.slide-style pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
border-radius: .3em
}
.slide-style :not(pre)>code[class*="language-"],.slide-style pre[class*="language-"] {
background: #272822
}
.slide-style :not(pre)>code[class*="language-"] {
padding: .1em;
border-radius: .3em
}
.slide-style .token.comment,.slide-style .token.prolog,.slide-style .token.doctype,.slide-style .token.cdata {
color: slategray
}
.slide-style .token.punctuation {
color: #f8f8f2
}
.slide-style .namespace {
opacity: .7
}
.slide-style .token.property,.slide-style .token.tag,.slide-style .token.constant,.slide-style .token.symbol,.slide-style .token.deleted {
color: #f92672
}
.slide-style .token.boolean,.slide-style .token.number {
color: #ae81ff
}
.slide-style .token.selector,.slide-style .token.attr-name,.slide-style .token.string,.slide-style .token.char,.slide-style .token.builtin,.slide-style .token.inserted {
color: #a6e22e
}
.slide-style .token.operator,.slide-style .token.entity,.slide-style .token.url,.slide-style .language-css .token.string,.slide-style .style .token.string,.slide-style .token.variable {
color: #f8f8f2
}
.slide-style .token.atrule,.slide-style .token.attr-value {
color: #e6db74
}
.slide-style .token.keyword {
color: #66d9ef
}
.slide-style .token.regex {
color: #fd971f
}
.slide-style .token.important {
color: #fd971f;
font-weight: 700
}
.slide-style .token.entity {
cursor: help
}
.slide-style .bespoke-parent {
position: relative;
}
.riker-grin{background-image:url(../images/get-infrastructure-right/riker-grin.jpg);background-position-y:12% !important}
.picard-wtf{background-image:url(../images/get-infrastructure-right/picard-wtf.jpg)}
.riker-grin,.picard-wtf{opacity:.75 !important}
.slide-style .picard-wtf-slide,.slide-style .riker-grin-slide{height:16em;padding:1em}
.slide-style .light-bg {
background-color: #fff;
}
.slide-style .light-bg,.slide-style .light-bg code[class*="language-"],.slide-style .light-bg pre[class*="language-"] {
color: #333!important;
}
.slide-style .light-bg code[class*="language-"] .token.operator,.slide-style .light-bg pre[class*="language-"] .token.operator,.slide-style .light-bg code[class*="language-"] .token.punctuation,.slide-style .light-bg pre[class*="language-"] .token.punctuation {
color: #555!important
}
.slide-style .light-bg.bespoke-backdrop-active {
opacity: 1;
}
.slide-style .pin {
position: absolute;
left: 0;
right: 0;
}
.slide-style .pin.top {
top: 10%;
}
.slide-style .pin.bottom {
bottom: 10%;
}
.slide-style .italic {
font-style: italic;
text-transform: none;
font-family: didot, times new roman, serif
}
.slide-style .tiny-code code[class*="language-"],.slide-style .tiny-code pre[class*="language-"] {
font-size: .8em;
line-height: 1
}
.slide-style .bespoke-slide {
padding: 1em;
zoom: .9;
position: relative;
}
.slide-style h1 {font-size:2em}
.slide-style h2 {font-size:1.5em;}
.slide-style h3 {font-size:1.2em;}
.post .slide-style pre {
border: 0;
}
.post .slide-style pre code {
border: 0;
background-color: transparent;
padding: 0;
}
#slides {
display: none;
opacity: 0;
transition: opacity 1s;
transition-timing-function: ease-out;
}
#slides.open {
display: block;
}
#slides.visible {
opacity: 1;
}
#slides iframe {
width: 100%;
height: 350px;
border: 0;
}
a#open-slides .caret {
display: inline-block;
-webkit-transition: -webkit-transform 0.5s;
transition: transform 0.5s;
-webkit-transform:rotate(0deg) translateY(0);
transform:rotate(0deg) translateY(0);
}
a#open-slides.pressed .caret {
-webkit-transform:rotate(180deg) translateY(-3px);
transform:rotate(180deg) translateY(-3px);
}
</style>
<div class="brooklynjs-box">
<div class="brooklynjs-logo-box">
<div class="brooklynjs-logo">
Brooklyn
<span class="j">J</span>
<span class="s">S</span>
</div>
</div>
<div class="brooklynjs-box-caption">
<p>This is a write-up of <a href="https://twitter.com/brooklyn_js/status/545755653160308738">a talk</a> <a href="https://twitter.com/RobbieTheGeek/status/545755219154731008">I gave</a> at <a href="http://brooklynjs.com/">BrooklynJS</a> on 12/18/2014,
<br>titled <a href="http://jimmy.schementi.com/brooklynjs-20141218/">“Build apps, not infrastructure”</a>.</p>
<p>Follow along with <a id="open-slides" href="javascript:void(0)">the slides <span class="caret">&blacktriangledown;</span></a></p>
</div>
<div id="slides">
<iframe src="http://jimmy.schementi.com/brooklynjs-20141218/"></iframe>
<p style="margin: 0; font-size: .75em; text-align: center;">Use arrow keys or swipe to control slides | <a href="http://jimmy.schementi.com/brooklynjs-20141218/" target="_blank">Open slides in a new window</a></p>
</div>
</div>
<script>
var openSlidesLink = document.querySelector('#open-slides');
var slides = document.querySelector('#slides');
openSlidesLink.addEventListener('click', function () {
slides.classList.toggle('open');
setTimeout(function () {
slides.classList.toggle('visible');
}, 20);
openSlidesLink.classList.toggle('pressed');
document.querySelector('#slides iframe').focus();
}, false);
</script>
<p>While most of us love building apps, we&#39;d also love it if people
used them, and if we&#39;re lucky, <strong>lots of people</strong>. Problem is, then we really need
to care about how our app runs and scales, and it&#39;s best to get it figured
out before that moment of fame arrives. Let’s look at a few of the tools and
services that you can use to manage your infrastructure, so you can spend more
time building your apps, and less dealing with keeping your app running.</p>
<div class="slide-style">
<article class="bespoke-parent">
<section class="bespoke-slide bespoke-active">
<h3 class="bullet bespoke-bullet bespoke-bullet-active bespoke-bullet-current">Have you ever...</h3>
<div>
<h2>Changed code</h2>
<h3>directly in</h3>
<h2>production?</h2>
</div>
<br>
</section>
<div class="emphatic bespoke-backdrop bespoke-backdrop-active"></div>
</article>
</div>
<p>Yes, we all have changed code directly in production <em>(and you’re
lying if you say you haven’t)</em>. We do this <strong>despite</strong> knowning that
it’s horrible:</p>
<ul>
<li>How many times have you found someone changed production directly
and <strong>forgot to check it in</strong>?</li>
<li>Or made <em>[what you thought was]</em> a simple code change to fix a specific
problem, but instead it revealed further problems.</li>
<li>Or users seeing intermittent brokenness while you make changes.</li>
<li>Or how do you know it works if you haven’t written tests for it?</li>
<li>Or! OR!</li>
</ul>
<blockquote>
<p>Heck, a company even has the person editing code in production <a href="http://www.bnj.com/blog/cowboy-coding-pink-sombrero/" title="Cowboy Coding">don a
pink sombrero</a> to bring awareness to “Cowboy Coding”:</p>
<p><img src="/images/get-infrastructure-right/cowboy-coding.jpg" alt="Cowboy coding" title="Cowboy Coding"></p>
</blockquote>
<p>Our reasons for making changes directly in production are usually good.
<em>Sometimes they’re not.</em> Regardless, we need to do this because our <strong>deployment
processes aren&#39;t automated enough to <em>safely</em> do this</strong>.</p>
<p><span class="center">
<img src="/images/get-infrastructure-right/automate-all-the-things.png" alt="Automate all the things" title="Automate All The Things">
</span></p>
<p>Think about it - if we could quickly write a fix in a clone of production, test
it, and push it to production in seconds, wouldn’t we do that instead?</p>
<p>It’s a lot of work to fully automate deployments, so most people have a fairly
<strong>manual deployment process</strong>. Which is crazy, considering we’re programmers - <strong>all
we do is automate.</strong></p>
<div class="slide-style">
<article class="bespoke-parent">
<section class="bespoke-slide bespoke-active">
<h2 class="bullet bespoke-bullet bespoke-bullet-active"><span>Application</span><span class="bullet italic bespoke-bullet bespoke-bullet-active">&nbsp;(feature)</span></h2>
<h3>vs.</h3>
<h2><span>Infrastructure</span><span class="bullet italic bespoke-bullet bespoke-bullet-active bespoke-bullet-current">&nbsp;(chore)</span></h2>
</section>
</article>
</div>
<p>This happens mainly because <strong>we prioritize features</strong>, or
enhancements to our applications, <strong>over chores</strong>, which can be enhancements to our
infrastructure. This distinction comes from <a href="http://en.wikipedia.org/wiki/Scrum_%28software_development%29">Scrum</a>, where you&#39;re rewarded
for completing features, as those &quot;add business value&quot;...</p>
<p><span class="center"><img src="/images/get-infrastructure-right/bullshit.jpg" alt="What if I told you that&#39;s bullshit" title="What if I told you... that&#39;s bullshit"></span></p>
<p><strong>Complete and utter bullshit...</strong></p>
<div class="slide-style">
<article class="bespoke-parent">
<section class="bespoke-slide bespoke-active">
<h2>Prioritizing</h2>
<h2>infrastructure</h2>
<h3>makes it easier to</h3>
<h2>ship features</h2>
</section>
</article>
</div>
<p><strong>A better infrastructure makes it easier to ship features.</strong> A shitty/non-existant
infrastructure makes adding features exponentially harder as the system gets more
complicated. Therefore, <strong>infrastructure improvements are really just features as
well</strong> - as they do provide end-user value, <em>eventually</em>.</p>
<p>For example, most people would consider “User Signup” to be a feature, as a user interacts with
it directly. Though, at the same time, it&#39;s more part of your infrastructure,
as it&#39;s not the product itself, but <em>a necessary evil to use the product</em>. But,
you’d never make signup be a manual process, <a href="http://moven.com" title="Fuck you!">as that would mean no one would
sign up and you’d have no users</a>.</p>
<p><span class="center"><img src="/images/get-infrastructure-right/bad-time.jpg" alt="If you manually do anything, you&#39;ll have a bad time" title="If you manually do anything, you&#39;re going to have a bad time."></span></p>
<p>Same should go for
deployments - if it’s not automatic, you’ll be <strong>afraid of deploying</strong>, and
favor large deployments, which will <strong>create more bugs</strong>, and a slew of other
anti-patterns will become part of your process. <strong>To build a great product, you
need to have an equally great infrastructure</strong>. Your users will feel the pain when
your infrastructure doesn’t support your ability to enhance your product.</p>
<div class="slide-style">
<article class="bespoke-parent">
<section class="bespoke-slide bespoke-active">
<h3>Think of</h3>
<h2>infrastructure</h2>
<h3>as a</h3>
<h2>product</h2>
<h3>you provide to</h3>
<h2>yourself</h2>
<br>
</section>
<div class="emphatic bespoke-backdrop bespoke-backdrop-active"></div>
</article>
</div>
<p><em>Whoa, far out man...</em></p>
<p>So, what would we want this infrastructure-as-a-product to do for us?</p>
<ol>
<li><p><strong>Runs the <a href="http://12factor.net" title="Twelve-Factor App">Twelve-Factor App</a></strong></p>
<p>This methology of building web applications and services leads to more
maintainable and scalable products. We’ll want our infrastructure to run
these apps, as these are the apps we’ll write. <a href="http://12factor.net" title="Twelve-Factor App">Read more about 12-factor
apps</a>.</p></li>
<li><p><strong>Deploy a new app</strong></p>
<p>New apps should be able to be deployed to any environment <em>within minutes</em>.
Given that we prefer <a href="http://martinfowler.com/articles/microservices.html">micro-services</a> over more monolithic architectures,
this is an important feature - new server provisioning will happen very
often. Infrastructures which requires significant effort to provision new
servers tend to avoid this patter, leading to an application which is <strong>harder
to scale and evolve</strong>.</p></li>
<li><p><strong>Automated scaling</strong></p>
<p>Every web app or service should be behind its own load-balancer, which you
can easily add or remove individual servers to. The creation of these
servers should be fully-automated to allow the load-balancer to create more
instance for you.</p></li>
<li><p><strong>Deploying should not introduce downtime</strong></p>
<p>Deploying an existing app or service shouldn’t make itself unavailable during
deployment. It should also allow for rollback, in case a new deployment isn’t
functioning properly, and versioning, to run multiple versions of the same
app.</p></li>
<li><p><strong>Create and clone environments</strong></p>
<p>Environments, a collection of all servers and configuration, should be
easily created or cloned. This environment can be anywhere - in the cloud,
or locally to develop against.</p></li>
<li><p><strong>Everything is automated</strong></p>
<p>Minimal manual processes should be involving in doing any of the above
features. Any modifications made to a default environment should be
repeatable.</p></li>
</ol>
<p>Sounds awesome, right? Does it already exist? Does it <em>kind of</em> already exist?
Let’s see what tools and services already exist that could help us out:</p>
<p><span class="center">
<img src="/images/get-infrastructure-right/heroku-logo.jpg" alt="Heroku" title="Heroku">
</span></p>
<p><a href="https://www.heroku.com/">Heroku</a> is “the” platform-as-a-service. It popularized many of the
<a href="http://12factor.net" title="Twelve-Factor App">12-factor app</a> practices. It was the first to use <code>git push</code> to trigger deployments.
Most importantly, it provides developers with a clean abstraction of an app,
hiding the complexities how to run the app. While <a href="https://www.heroku.com/">Heroku</a>’s featureset is almost
exactly what we want, this abstraction comes at a price - quite literally.
Heroku is fairly expensive ($34.50/month for the low-end 2-server setup). It becomes more
expensive as you use add-ons (for example, $50/month for low-end Postgres).
Also, using Heroku is much more difficult (and expensive) to use for a utility
server, like Jenkins or Graphite, which may have higher CPU requirements
(nothing worse than slow builds).</p>
<p><em>That’s not to say if you’re using Heroku you shouldn’t, it’s a great service.
Just be aware of the pros and cons.</em></p>
<p>Though, how Heroku deploys applications is very interesting. Heroku has a
concept of a <a href="https://devcenter.heroku.com/articles/buildpacks">buildpack</a>, which contains the logic to detect a specific type of
application and deploy it. <a href="https://devcenter.heroku.com/articles/buildpacks">Heroku Buildpacks</a> are all open-source,
meaning you can write your own, allowing Heroku to run almost anything. We can
also use <a href="https://devcenter.heroku.com/articles/buildpacks">Heroku Buildpacks</a> to provision our own servers...</p>
<p><span class="center">
<img src="/images/get-infrastructure-right/docker.png" alt="Docker" title="Docker">
</span></p>
<p><a href="https://www.docker.com/">Docker</a> provides application containers, which provides the applications with an
isolated view of the operating system - their own process ID space, filesystem,
and network interfaces. It also provides contraints on system resources (memory,
CPU, network I/O).</p>
<p>Essentially <a href="https://www.docker.com/">Docker</a> can be used to provision and deploy applications, as an
alternative to <a href="https://devcenter.heroku.com/articles/buildpacks">Heroku Buildpacks</a>. The difference is <a href="https://www.docker.com/">Docker</a> can
be used to run an identical environment locally as well as when deployed, and
can run other apps like databases.</p>
<p><span class="center">
<img src="/images/get-infrastructure-right/aws.png" alt="Amazon Web Services" title="Amazon Web Services">
</span></p>
<p><a href="http://aws.amazon.com">Amazon Web Services (AWS)</a> is a <strong>massive</strong> collection of services. <strong>37 different
services</strong> to be exact:</p>
<p><img src="/images/get-infrastructure-right/AWS_Management_Console.png" alt="Amazon Web Services Features" title="AWS Features"></p>
<p>At the core is <a href="http://aws.amazon.com/ec2/" title="Amazon EC2">Elastic Compute Cloud (EC2)</a>, which allows you to run and manage
arbitrary <a href="http://en.wikipedia.org/wiki/Virtual_machine">virtual machines</a> in Amazon&#39;s data centers. <a href="http://aws.amazon.com/ec2/" title="Amazon EC2">EC2</a> also has sub-services to help route network traffic
to your <a href="http://en.wikipedia.org/wiki/Virtual_machine">VMs</a>, specifically <a href="http://aws.amazon.com/elasticloadbalancing/">a TCP and HTTP load-balancer</a>, as well as <a href="http://aws.amazon.com/autoscaling/">Auto Scaling</a>,
which helps you launch <a href="http://aws.amazon.com/ec2/instance-types/">instances</a> and add them to a load-balancer.</p>
<p>Another useful service is <a href="http://aws.amazon.com/s3/">Simple Storage Service (S3)</a>, which stores
arbitrary data like a file system. It can also serve those files over HTTP, making it an ideal
static HTTP server, as you don’t have to manage servers or load-balancers.</p>
<p>The <em>35 other services</em> do lots of useful things, like various data storage
services, <a href="http://aws.amazon.com/vpc/">private networks</a>, <a href="http://aws.amazon.com/route53/">DNS</a>, app and mobile services, deployment/provisioning stuff, oh my!
It can get very confusing for newcomers and experienced engineer alike,
as some of the services overlap in functionality. For example,
<a href="http://aws.amazon.com/opsworks/">OpsWorks</a>, <a href="http://aws.amazon.com/cloudformation/">CloudFormation</a>, and <a href="http://aws.amazon.com/elasticbeanstalk/">Beanstalk</a>
all can do very similar things. Or complete with existing Open Source offerings, like
<a href="http://aws.amazon.com/dynamodb/">DynamoDB</a> vs. <a href="http://www.mongodb.org/">MongoDB</a>.</p>
<p><a href="http://aws.amazon.com/elasticbeanstalk/">Elastic Beanstalk</a> is worth noting, because it provides a similar
feature-set to Heroku - it can deploy applications to EC2 instances, and
auto-configures auto scaling and load balancing. However, the pre-configured
environments are awkward to configure, using the special <code>.elasticbeanstalk</code>
and <code>.ebextensions</code> directories, and creating a
<a href="http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.customenv.html">custom AMI for Elastic Beanstalk</a> somewhat violates
the “infrastructure as code” tenant. Also, it’s all or nothing - so if
your application isn’t supported by <a href="http://aws.amazon.com/elasticbeanstalk/">Elastic Beanstalk</a>, like
<a href="https://golang.org/">GoLang</a>, you can’t use it.</p>
<blockquote>
<p>Recently, Amazon improved <a href="http://aws.amazon.com/elasticbeanstalk/">Elastic Beanstalk</a> by adding support
for <a href="https://www.docker.com/">Docker</a>, which can be used to avoid all the environment weirdnesses,
standardize provisioning, and support other languages. It also supports
<a href="http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.rollingupdates.html">rolling updates</a>, meaning there’s no downtime during a deployment.</p>
</blockquote>
<p>Amazon has recently added some new services, currently in preview, which are
promising:</p>
<ul>
<li><a href="http://aws.amazon.com/codedeploy/">CodeDeploy</a> manages applications and how to deploy them (some overlap with Beanstalk, but a bit more general)</li>
<li><a href="http://aws.amazon.com/ecs/">EC2 Container Service</a> supports clustering of Docker containers</li>
<li><a href="http://aws.amazon.com/lambda/">Lambda</a> - respond to events with code.</li>
</ul>
<p><span class="center">
<img src="/images/get-infrastructure-right/docean.svg" alt="Digital Ocean" title="Digital Ocean">
</span></p>
<p>For those completely overwelmed by <a href="http://aws.amazon.com">AWS</a>, or just looking for something simpler,
<a href="https://www.digitalocean.com/">Digital Ocean</a> is basically the equivalent of <a href="http://aws.amazon.com/ec2/" title="Amazon EC2">EC2</a> and <a href="http://aws.amazon.com/route53/">Route53</a>,
but with an awesome user interface for both the website and the <a href="https://developers.digitalocean.com/">API</a>, making it
much easier to work with.</p>
<p>Because it’s only for running <a href="https://www.digitalocean.com/community/tutorials/how-to-create-your-first-digitalocean-droplet-virtual-server">droplets</a> (their word for VMs), any load
balancing needs to be done with another dedicated <a href="https://www.digitalocean.com/community/tutorials/how-to-create-your-first-digitalocean-droplet-virtual-server">droplet</a> (eg. <a href="http://www.haproxy.org/">HAProxy</a>),
and scaled manually.</p>
<div class="slide-style">
<div class="bespoke-parent">
<section class="bespoke-slide bespoke-active">
<h3 style="font-size: 1.5em">Feels like something's missing...</h3>
</section>
<div class="emphatic bespoke-backdrop bespoke-backdrop-active"></div>
</div>
</div>
<p>Seems like we can use all this for the major features of our infrastructure, but
nothing integrates it all together and makes it as easy as Heroku.</p>
<div class="slide-style">
<article class="bespoke-parent riker-grin-slide">
<section class="bespoke-slide bespoke-active" style="zoom: 0.947872340425532;">
<div class="pin top">
<h2>Riker</h2>
<h3>Heroku-like application deployments for<br>Amazon Web Services.</h3>
</div>
</section>
<div class="riker-grin bespoke-backdrop bespoke-backdrop-active"></div>
</article>
</div>
<p>Riker gives you Heroku-like application deployments for Amazon Web Services. It
automates all the best-practices of application deployment, so you don’t have to
piece things together.</p>
<p>Riker deploys any application with a <a href="https://devcenter.heroku.com/articles/buildpacks">buildpack</a> to <a href="http://aws.amazon.com">AWS</a>, and
automatically configures load balancing and auto scaling for you, as well as
manages rolling deployments. It also can deploy static websites to S3.</p>
<p>Next I’d like to make the target “cloud” be extensible (most likely <a href="https://www.digitalocean.com/">Digital
Ocean</a> as a first), support <a href="https://docs.docker.com/reference/builder/">Dockerfiles</a> as an alternative
to <a href="https://devcenter.heroku.com/articles/buildpacks">buildpacks</a>, and use some of <a href="http://aws.amazon.com">AWS</a>’s new features, like the <a href="http://aws.amazon.com/ecs/">EC2
Container Service</a>, <a href="http://aws.amazon.com/codedeploy/">CodeDeploy</a>, and <a href="http://aws.amazon.com/lambda/">Lambda</a>.</p>
<p>Check out my <a href="/riker-heroku-like-app-deploy-for-aws">initial post about Riker</a>, as it’s the same content
I spoke about in my talk. Here’s some other useful links:</p>
<ul>
<li><a href="https://github.com/jschementi/riker">Project on GitHub</a></li>
<li><a href="https://pypi.python.org/pypi/riker">Riker on Python Package Index</a></li>
<li><a href="https://github.com/jschementi/riker/issues">Issues list</a> <em>(for roadmap as well as report bugs)</em></li>
<li><a href="https://github.com/jschementi/riker/pulls">Pull requests</a> would be much appreciated!</li>
</ul>
<p>If you want to <em>(eventually)</em> spend less time managing your infrastructure, and
more time building products, or are just interested in making infrastructure
management better, give Riker a try and come help me build it!</p>
<div class="slide-style">
<article class="bespoke-parent picard-wtf-slide">
<section class="bespoke-slide bespoke-active" style="zoom: 0.947872340425532;">
<h3 style="padding-left: 40%;padding-top: 5%">You're the captain, make Riker your #1</h3>
</section>
<div class="picard-wtf bespoke-backdrop bespoke-backdrop-active"></div>
</article>
</div>
<p><em>Yeah, I’m a Trekky...</em></p>
<!--
#### Old blog post
I’d much rather focus on building a system, knowing that deployments and
scaling are already And if I push that work off until the system is
bigger or traffic start increasing, it takes even more time. Unless I use
Heroku; then I spend very little time, but mainly because I control very
little.
As the applications we build for the web get more complex, so does deploying
and managing them. Remember when deploying your website was no more complex
than FTP-ing PHP files to your servers, and maybe running some MySQL scripts.
Your servers were either hosted by another company, or your own hardware, and
you just had one or two. You setup Apache and MySQL just once, and didn't
really have to think about your infrastructure much more than that - you spent
all your time focused on building your website.
How the times have changed. Now, we build web applications, and boy are they
more complex. The web server is usually just a forward proxy to your
application's processes, which themselves run a web server, and are written in
various programming languages. These applications do more than just generate
HTML - they also serve data which is consumed by any number of web browser and
native client applications. To accomplish this, your application's depend on
various technologies like key-value stores, message queues, and possibly
different types of relational and object databases. And all this runs on
virtual machines. All this extra complexity means a bunch more ways things can
break, so each component needs to be monitored. All this means more time
managing the infrastructure, and less time building your application.
There are no shortage of tools meant to help manage this infrastructure,
too many to name here. However, the infrastructure still gets in our way -
it's still way to hard to ship features to our users. We need to get back to
the simplicity of just publishing your code, and the "infrastructure" does
what's necessary to deploy it.
One service has set the standard for this - Heroku. With a few commands, you
can get your application deployed to the internet, without needing to deal with
setting up virtual machines. For most applications this is great when they
first start out, but that lack of control starts to become a burdeon as they
grow. Also, while Heroku allows you to manually scale up your applications, the cost of doing so becomes fairly high.
#### &lt;/end&gt; Old blog post
--><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=imJJOp5hM3E:ykSsySA48DI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=imJJOp5hM3E:ykSsySA48DI:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=imJJOp5hM3E:ykSsySA48DI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=imJJOp5hM3E:ykSsySA48DI:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=imJJOp5hM3E:ykSsySA48DI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=imJJOp5hM3E:ykSsySA48DI:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=imJJOp5hM3E:ykSsySA48DI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jimmy-thinking/~4/imJJOp5hM3E" height="1" width="1" alt=""/>Tue, 30 Dec 2014 00:00:00 +0000http://feedproxy.google.com/~r/jimmy-thinking/~3/imJJOp5hM3E/get-infrastructure-right
http://jimmy.schementi.com/get-infrastructure-righthttp://jimmy.schementi.com/get-infrastructure-rightRiker - Heroku-like app deployments for AWS<p><a href="https://github.com/jschementi/riker" title="Riker"><img src="/images/riker-phaser.jpg" alt="William Riker"></a></p>
<p><a href="https://github.com/jschementi/riker" title="Riker">Riker</a> turns <a href="http://aws.amazon.com/" title="Amazon Web Services">Amazon Web Services</a> into your very own
<a href="http://en.wikipedia.org/wiki/Platform_as_a_service" title="Platform as a Service">Platform as a Service</a>, giving you the same ease-of-use that platforms like <a href="http://heroku.com" title="Heroku">Heroku</a>
provide, while retaining the control that is attractive about <a href="http://aws.amazon.com/" title="Amazon Web Services">AWS</a>.</p>
<h3>Getting Started</h3>
<p>Getting started with <a href="https://github.com/jschementi/riker" title="Riker">Riker</a> is easy: just install it using <a href="http://pip.readthedocs.org/en/latest/installing.html#install-pip" title="Python Install Python">pip</a> and Riker
will prompt you for the necessary information it needs:</p>
<div class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>pip install riker
<span class="nv">$ </span>riker config</code></pre></div>
<h3>Deploy a Node.js app</h3>
<p>First, let’s clone a sample <a href="http://nodejs.org/" title="Node.js">Node.js</a> app:</p>
<div class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>git clone git@github.com:heroku/node-js-sample.git
<span class="nv">$ </span><span class="nb">cd </span>node-js-sample</code></pre></div>
<p>Then deploy it with just one command:</p>
<div class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>riker deploy</code></pre></div>
<p>And open it in your default web browser:</p>
<div class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>riker open</code></pre></div>
<p>That’s it! While this example deploys a sample <a href="http://nodejs.org/" title="Node.js">Node.js</a> application, any
language can be deployed, since Riker uses <a href="https://devcenter.heroku.com/articles/buildpacks" title="Heroku Buildpacks">Heroku Buildpacks</a>. <a href="https://github.com/jschementi/riker/issues/30">More
information on exactly what buildpacks Riker supports, and how to use a custom
buildpack</a>.</p>
<h3>Deploy a static website</h3>
<p>Riker can also be used to deploy static websites to <a href="http://aws.amazon.com/s3/" title="Simple Storage Service">S3</a>, rather than running
<a href="http://nginx.org/" title="NGINX">nginx</a> or <a href="http://httpd.apache.org/" title="Apache">apache</a> in an <a href="http://aws.amazon.com/ec2/" title="Elastic Compute Cloud">EC2</a> instance to serve static files:</p>
<p>First, generate a static website:</p>
<div class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>mkdir static-website <span class="o">&amp;&amp;</span> <span class="nb">cd </span>static-website
<span class="nv">$ </span><span class="nb">echo</span> <span class="s2">&quot;Hello, World&quot;</span> &gt; index.html
<span class="nv">$ </span>touch .s3 <span class="c"># tells Riker to deploy to Amazon S3</span>
<span class="nv">$ </span>git init <span class="o">&amp;&amp;</span> git add -A <span class="o">&amp;&amp;</span> git commit -m <span class="s2">&quot;Initial commit&quot;</span></code></pre></div>
<p>Then use the same commands as before to deploy and open the website:</p>
<div class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>riker deploy
<span class="nv">$ </span>riker open</code></pre></div>
<h3>Scalable, zero-downtime deployments</h3>
<p>Riker provides a scalable mode (<code>--scale</code>), where <a href="http://aws.amazon.com/elasticloadbalancing/" title="Elastic Load Balancing">load balancing</a> and
<a href="http://aws.amazon.com/autoscaling/" title="Auto-scaling">auto-scaling</a> are configured for you. This also ensures zero-downtime during
deployments.</p>
<div class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>riker deploy --scale</code></pre></div>
<h3>How It Works</h3>
<p>Riker provides a set of best-practices and structure to your infrastructure,
while leaning on as much of the features AWS provides as possible.</p>
<ul>
<li>Load Balancing: <a href="http://aws.amazon.com/elasticloadbalancing/" title="Elastic Load Balancing">Elastic Load Balancer (ELB)</a></li>
<li>Scaling: <a href="http://aws.amazon.com/autoscaling/" title="Auto-scaling">EC2 Auto-Scaling and Launch Configurations</a></li>
<li>DNS: <a href="http://aws.amazon.com/route53/" title="Route 53">Route 53</a></li>
<li>Static website hosting: <a href="http://aws.amazon.com/s3/" title="Simple Storage Service">Simple Storage Service (S3)</a></li>
</ul>
<p>Riker doesn’t require its own server to be running; it’s just a deployment
tool (though it’s best to run Riker in a <a href="http://en.wikipedia.org/wiki/Continuous_integration" title="Continuous Integration">CI</a> server like <a href="http://jenkins-ci.org/" title="Jenkins CI">Jenkins</a>).</p>
<p>Riker also abstracts away the <a href="http://aws.amazon.com/ec2/" title="Elastic Compute Cloud">EC2</a> instances, and instead lets you only care
about the application itself: code, dependencies, and configuration. Riker
makes your instances easy to destroy and recreate, removing the need to ever
manually provision a machine. This also makes scaling trivial. To enable this
abstraction, Riker uses Docker to run your application in its own sandbox,
as well as <a href="https://devcenter.heroku.com/articles/buildpacks" title="Heroku Buildpacks">Heroku Buildpacks</a> to deploy many different types of applications.
Today, Riker also uses <a href="https://github.com/progrium/dokku" title="Dokku">Dokku</a>, but may move away from it to allow Riker to also
run your application locally during development, but more about that later.</p>
<p>By default, Riker will deploy changes directly to existing instances.
However, with the <code>--scale</code> flag, Riker will deploy changes to new instances,
and only swap old instances out for new instances when the new instances
become healthy, and the old instances no longer have active connections.</p>
<h3>Disclaimer</h3>
<p>While Riker is in active development, it’s probably not ready for prime-time,
unless you’re really willing to help contribute and test things out.</p>
<h3>Contribute</h3>
<p>There are many ways you can help make Riker better:</p>
<ul>
<li><strong>Use it!</strong> <a href="https://github.com/jschementi/riker/issues" title="Riker Issues">Report bugs, suggest features and ask questions on GitHub</a></li>
<li><strong>Write documentation</strong>: Anything you feel requires documentation, please feel
free to write it in the <a href="https://github.com/jschementi/riker/wiki" title="Riker Wiki">Wiki</a>.
<a href="http://fusiongrokker.com/post/how-you-can-contribute-to-taffy-documentation">Please follow these instructions for contributing to Wikis</a></li>
<li><strong>Write code</strong>: Either from the <a href="https://github.com/jschementi/riker/issues" title="Riker Issues">Issues list</a>,
or your own idea.
<a href="https://github.com/jschementi/riker/pulls" title="Riker Pull Requests">Pull requests are encouraged!</a></li>
</ul>
<p>Let me know what you think! Look for subsequent posts about the rationale behind
Riker and why it’s different than other comparable services.</p>
<div style="text-align:center; font-style: italic;">You’re the captain - make Riker your "Number One"</div>
<p><a href="https://github.com/jschementi/riker" title="Riker"><img src="/images/riker-grin.jpg" alt="William Riker"></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=3GV5fNno-W0:-xZJKYraa9w:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=3GV5fNno-W0:-xZJKYraa9w:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=3GV5fNno-W0:-xZJKYraa9w:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=3GV5fNno-W0:-xZJKYraa9w:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=3GV5fNno-W0:-xZJKYraa9w:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=3GV5fNno-W0:-xZJKYraa9w:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=3GV5fNno-W0:-xZJKYraa9w:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jimmy-thinking/~4/3GV5fNno-W0" height="1" width="1" alt=""/>Wed, 24 Sep 2014 00:00:00 +0000http://feedproxy.google.com/~r/jimmy-thinking/~3/3GV5fNno-W0/riker-heroku-like-app-deploy-for-aws
http://jimmy.schementi.com/riker-heroku-like-app-deploy-for-awshttp://jimmy.schementi.com/riker-heroku-like-app-deploy-for-awsSplitting up a Git repo<p>When it comes to organizing Git repositories, there&#39;s only one way to do it:
<strong>a repository per project or component</strong> (a web server, an iOS app, etc...).</p>
<p>If you&#39;ve done anything other than that, <strong>you&#39;ve fucked up</strong>. Maybe you have a
single repository for everything? Some combination? Sure, it might be easier to just
have one repository, but as your system grows, the ramifications of that fuck-up
become clear:</p>
<ul>
<li><p>A 1-line change to the app performs a full-redeploy of your web-server -
now you have to have your CI server only build certain jobs based on
directory&#39;s touched. <strong>Yuck.</strong></p></li>
<li><p>Every single server has the code for all the other servers. Now you have to
perform a build step to remove files from deployments. <strong>Yuck.</strong></p></li>
<li><p>Large commits cutting across multiple components. Commit messages could be
considered novels. Now we have to selectively commit certain files that touch a
server, and certain files that touch the app, etc. <strong>Yuck.</strong></p></li>
</ul>
<p>If this sounds like your project, don&#39;t keep working around the problem - <strong>let&#39;s
fix it.</strong> It&#39;s probably going to be a bit of work, but it&#39;s necessary, so take a
deep breath, and let&#39;s get started.</p>
<p>The first choice you have to make is whether to preserve history or not. For
almost all cases you should preserve history, but if for some reason
you decide it&#39;s not important, then <em>&quot;these aren&#39;t the droids you&#39;re looking for&quot;</em>.
You just need to create new repositories, copy files to each as appropriate, and
you&#39;re done. That might be the right choice for your project, but this isn&#39;t
the post for you.</p>
<p>Git gives us many tools to rewrite history, so let&#39;s look at situations you&#39;ll
run into, and how to use Git to deal with them.</p>
<h3>Extract a sub-directory</h3>
<p>This is the best-case scenario: everything is perfect about your repository,
only you have each project/component in a sub-directory of your large repo.
For this, <code>git subtree split</code> is exactly what you want.</p>
<div class="highlight"><pre><code class="language-text" data-lang="text">git subtree split -prefix=subdir_to_remove -b new_project_branch
</code></pre></div>
<blockquote>
<p>For some older versions of git, the <code>subtree</code> subcommand may be unavailable.
Instead, you can use the <code>filter-branch</code> subcommand:</p>
<div class="highlight"><pre><code class="language-text" data-lang="text">git filter-branch --subdirectory-filter subdir_to_remove new_project_branch
</code></pre></div></blockquote>
<p>Then you can push each new branch to its own remote.</p>
<h3>Arbitrary paths</h3>
<p>What if a project has two top-level directories, or shares files between projects?
Maybe a <code>.env</code> or <code>Procfile</code>?
In this case you&#39;ll have to extract history by arbitrary paths.</p>
<p>To do this, first we remove all non-wanted files from all git commits with the
<code>git filter-branch</code> command. Any commits that do not touch those paths will be
removed because of the <code>--ignore-unmatch</code> flag.</p>
<div class="highlight"><pre><code class="language-text" data-lang="text">PATHS_TO_KEEP=&quot;./some_dir ./some_other_dir .env Procfile&quot;
git filter-branch -f --index-filter &quot;git rm --ignore-unmatch --cached -qr -- . &amp;&amp; git reset -q \$GIT_COMMIT -- $PATHS_TO_KEEP&quot; --prune-empty -- HEAD
</code></pre></div>
<blockquote>
<p>The <code>-- HEAD</code> means to only do this transformation in the current branch.
You can replace it with <code>-- --all</code> to do it across all branches. Or
<code>--tag-name-filter cat -- --all</code> to do it across all branches AND tags. Pick your poison.</p>
</blockquote>
<p>While this is great, empty merge commits are not removed by the last command!
A <code>parent-filter</code> can be used to rewrite commit parents to remove them:</p>
<div class="highlight"><pre><code class="language-text" data-lang="text">tmpfile=`mktemp -t splitgit`
chmod 755 $tmpfile
echo &#39;#!/usr/bin/env ruby
old_parents = gets.chomp.gsub(&quot;-p &quot;, &quot; &quot;)
new_parents = old_parents.empty? ? [] : `git show-branch --independent #{old_parents}`.split
puts new_parents.map{|p| &quot;-p &quot; + p}.join(&quot; &quot;)&#39; &gt; $tmpfile
git filter-branch -f --prune-empty --parent-filter $tmpfile HEAD
rm $tmpfile
</code></pre></div>
<blockquote>
<p>You can simplify this by writing $tmpfile to disk in a well-known location,
instead of using <code>mktemp</code> each time.</p>
</blockquote>
<h3>Moving files around</h3>
<p>Let&#39;s say a new repo should still have a file, but you want to change its
path in the new repo? If so, <code>tree-filter</code> can help with this. For this example,
we want to move an entire sub-directory up one level.</p>
<div class="highlight"><pre><code class="language-text" data-lang="text">git filter-branch -f --tree-filter &#39;shopt -s dotglob nullglob; test -d sub_dir &amp;&amp; mv sub_dir/* . || :&#39; HEAD
</code></pre></div>
<h3>Deleting files</h3>
<p>What if you just don&#39;t want a particualr file around?</p>
<div class="highlight"><pre><code class="language-text" data-lang="text">git filter-branch -f --index-filter &#39;git rm --cached --ignore-unmatch Rakefile&#39; --prune-empty -- HEAD
</code></pre></div>
<blockquote>
<p>We use <code>index-filter</code> here to not require files be checked out for each commit,
which makes it faster. This is different from <code>tree-filter</code> in that it checks out
each commit&#39;s files. This is good in that it lets you use <code>rm</code> and <code>test</code>, but is
slower. When formulating your own history manipulations, keep this in mind.</p>
</blockquote>
<h3>Keeping only certain lines in a file</h3>
<p>(I know, this is crazy...) What if, in your old repo, you had a configuration
file that was for all projects, but now you want to only keep commits that
affected the variables for the particuar sub-project? <code>tree-filter</code> + <code>cat</code> + <code>grep</code>:</p>
<div class="highlight"><pre><code class="language-text" data-lang="text">git filter-branch -f --tree-filter &#39;test -f .env &amp;&amp; cat .env | grep &quot;\(^VAR_X\|^VAR_Y\|^VAR_Z\)&quot; &gt; .newenv &amp;&amp; mv .newenv .env || :&#39; --prune-empty -- HEAD
</code></pre></div>
<h3>Fucking symlinks</h3>
<p>OK, this is harder, but all your fault. You have symlinks in your repo, presumably to
share code between projects. Bad. Share code through a package manager, a submodule,
or some other means, but not through a symlink.</p>
<p>This is a problem when your repository split makes a symlink invalid, since Git
stores symlinks as a file with its only contents a path.</p>
<p>To fix this, we&#39;ll convert all symlinks into hard links, which Git will then
treat as any other file and commit its contents.</p>
<p>Convert all symlinks to hard links (if the symlinks are relative paths):</p>
<div class="highlight"><pre><code class="language-text" data-lang="text">git filter-branch -f --tree-filter \
&#39;find . -type l -exec bash -c &#39;&quot;&#39;&quot;&#39;ln -f &quot;$(dirname &quot;$0&quot;)/&quot;&quot;$(readlink -n &quot;$0&quot;)&quot; &quot;$0&quot;&#39;&quot;&#39;&quot; {} \;&#39; \
--prune-empty -- HEAD
</code></pre></div>
<blockquote>
<p>If the paths are absolute, WTF? How the hell did that ever work to begin with??</p>
</blockquote>
<h3>Empty commits</h3>
<p>If for some reason you have empty commits (maybe you forgot a <code>--ignore-unmatch</code> ?),
you can remove them with a special <code>--commit-filter</code>:</p>
<div class="highlight"><pre><code class="language-text" data-lang="text">git filter-branch --commit-filter &#39;git_commit_non_empty_tree &quot;$@&quot;&#39; HEAD
</code></pre></div>
<h4>The initial commit is still empty, what gives?</h4>
<p>That&#39;s the only price your going to pay for not doing the right thing to start, so
be OK with it. Your initial commit is most likely going to be an empty one saying
&quot;Initial commit&quot; or whatever you said.</p>
<p>You could rebase your entire repository (<code>git rebase --interactive --root</code>)
but if you have any legitimate merge commits you&#39;ll find yourself attempting to merge
years old code in the right order. It&#39;s not worth it.</p>
<h3>Fixing author info</h3>
<p>If you notice certain committers used a non-company email, or there are commits
from non-human accounts, you can use a <code>--env-filter</code> to rewrite author and
committer name and emails. <a href="https://help.github.com/articles/changing-author-info">GitHub&#39;s Help site has a good example of this</a>.</p>
<h3>Holy crap I deleted the wrong thing/everything!</h3>
<p>No problem! If anything goes wrong, you can undo the last <code>filter-branch</code>:</p>
<div class="highlight"><pre><code class="language-text" data-lang="text">git reset --hard refs/original/refs/heads/master
</code></pre></div>
<h3>Next steps</h3>
<p>After you&#39;ve got all your new shiny respositories how you want them, you&#39;re may not
be entirely done. Some things that you probably need to do:</p>
<ul>
<li>Create new CI or deployment jobs to work against new repos</li>
<li>Reference GitHub issues in commits? Well, now <code>#1234</code> points to your new repo,
not the old one. To reference an issue in a different repo than the current one,
use <code>user/repo#1234</code> (and make it a habit to always reference them like that).
I&#39;ll leave it to the reader to figure out how to rewrite commit messages from
<code>#1234</code> to <code>user/repo#1234</code>.</li>
<li>Delete old code from old repo, and put a message up on your old repo telling
visitors where to look for the new repo.</li>
</ul>
<p>Happy history rewriting!</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=zzfaYymstoI:GIxj9_ZrUyE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=zzfaYymstoI:GIxj9_ZrUyE:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=zzfaYymstoI:GIxj9_ZrUyE:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=zzfaYymstoI:GIxj9_ZrUyE:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=zzfaYymstoI:GIxj9_ZrUyE:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=zzfaYymstoI:GIxj9_ZrUyE:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=zzfaYymstoI:GIxj9_ZrUyE:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jimmy-thinking/~4/zzfaYymstoI" height="1" width="1" alt=""/>Thu, 17 Jul 2014 18:19:00 +0000http://feedproxy.google.com/~r/jimmy-thinking/~3/zzfaYymstoI/splitting-up-a-git-repo
http://jimmy.schementi.com/splitting-up-a-git-repohttp://jimmy.schementi.com/splitting-up-a-git-repoSparklines in WPF and Silverlight<div class="post-content">
<p><a href="http://lh3.ggpht.com/_OqCZhp9yI0Q/TcdqGOwvLII/AAAAAAAAAXw/kv7ipoVOWWU/s1600-h/image%5B38%5D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_OqCZhp9yI0Q/TcdqHYBck1I/AAAAAAAAAX0/TfMiLAp5p9w/image_thumb%5B28%5D.png?imgmax=800" width="480" height="240"></a></p> <p>One seemingly-trivial-yet-recurring problem in financial software is the need for a live-updating line-chart. However, from multiple conversations with <a href="http://lab49.com" target="_blank">Lab49</a> folks, as well as from experience during my first project, I’ve learned that most WPF/Silverlight charting packages suck in various ways, especially if you’re updating their data frequently. Seems like everyone just rolls their own line chart and tailors it to each project, but doesn’t share it for some reason. I’d like to break that trend by sharing and early version of <a href="http://github.com/jschementi/sparkline" target="_blank">my own sparkline control for WPF and Silverlight</a>.</p> <p align="left"><a href="http://github.com/jschementi/sparkline"><strong><font size="3">http://github.com/jschementi/sparkline</font></strong></a></p> <p><strong>Sample Usage:</strong> </p><script src="https://gist.github.com/961143.js"> </script> <p>It’s implementation is very basic; <a href="https://github.com/jschementi/sparkline/blob/master/Schementi.Controls.Sparkline/Sparkline.xaml.cs#L255" target="_blank">Sparkline.AddTimeValue</a> constructs a point at the next time interval and adds it to a <a href="http://msdn.microsoft.com/en-us/library/system.windows.shapes.polyline.aspx" target="_blank">Polyline</a>. You can control the sparkline’s visuals, including adding visible points along the line and showing horizontal lines for the latest/highest/lowest values. The source builds assemblies for both .NET 4.0 and Silverlight 4.</p> <p>There are obvious features missing like rendered axis or variable x-axis (time) values, but hopefully this provides a simple starting place for anyone else needing a very simple updating line graph. </p> <p>By the way, <a href="http://decav.com/" target="_blank">Andre de Cavaignac</a>, a colleague of mine at Lab49, and Daniel Simon shared their own a while back: <a href="http://blog.lab49.com/archives/2028" target="_blank">Live Updating Line Graph in WPF</a>. Let me know if there are any others out there.</p> <p>Anyways, <a href="http://en.wikipedia.org/wiki/Mother's_Day" target="_blank">Happy Mother’s Day</a>!</p>
</div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=xP_4YMK-oso:jCSUqBU1Uko:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=xP_4YMK-oso:jCSUqBU1Uko:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=xP_4YMK-oso:jCSUqBU1Uko:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=xP_4YMK-oso:jCSUqBU1Uko:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=xP_4YMK-oso:jCSUqBU1Uko:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=xP_4YMK-oso:jCSUqBU1Uko:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=xP_4YMK-oso:jCSUqBU1Uko:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jimmy-thinking/~4/xP_4YMK-oso" height="1" width="1" alt=""/>Mon, 09 May 2011 04:15:00 +0000http://feedproxy.google.com/~r/jimmy-thinking/~3/xP_4YMK-oso/sparklines-in-wpf-and-silverlight.html
http://jimmy.schementi.com/2011/05/sparklines-in-wpf-and-silverlight.htmlhttp://jimmy.schementi.com/2011/05/sparklines-in-wpf-and-silverlight.htmlNYC CodeCamp 2011<div class="post-content">
<p>This past weekend I spoke at <a href="http://nyc.codecamp.us/" target="_blank">NYC CodeCamp 2011</a> about the <a href="http://github.com/IronLanguages" target="_blank">Iron Languages</a> project and dynamic languages on .NET; here are the slides:</p> <div style="width: 425px" id="__ss_7053366"><object id="__sse7053366" width="425" height="355"> <param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=jschementi-codecampnyc-20110219-110225011534-phpapp02&amp;rel=0&amp;stripped_title=jschementi-codecampnyc20110219&amp;userName=jschementi" /> <param name="allowFullScreen" value="true" /> <param name="allowScriptAccess" value="always" /> <embed name="__sse7053366" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=jschementi-codecampnyc-20110219-110225011534-phpapp02&amp;rel=0&amp;stripped_title=jschementi-codecampnyc20110219&amp;userName=jschementi" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed> </object> <p>Most of the demos were from previous talks, so look through my previous posts on <a href="http://ironruby.net" target="_blank">IronRuby</a> and <a href="http://ironpython.net" target="_blank">IronPython</a> for relevant demos.</p></div>
</div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=CgdGnN-h_5U:C--oGxmJXFQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=CgdGnN-h_5U:C--oGxmJXFQ:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=CgdGnN-h_5U:C--oGxmJXFQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=CgdGnN-h_5U:C--oGxmJXFQ:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=CgdGnN-h_5U:C--oGxmJXFQ:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=CgdGnN-h_5U:C--oGxmJXFQ:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=CgdGnN-h_5U:C--oGxmJXFQ:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jimmy-thinking/~4/CgdGnN-h_5U" height="1" width="1" alt=""/>Fri, 25 Feb 2011 07:50:00 +0000http://feedproxy.google.com/~r/jimmy-thinking/~3/CgdGnN-h_5U/nyc-codecamp-2011.html
http://jimmy.schementi.com/2011/02/nyc-codecamp-2011.htmlhttp://jimmy.schementi.com/2011/02/nyc-codecamp-2011.htmlLeadership of IronRuby and IronPython<div class="post-content">
<p>Now that <a href="http://www.flickr.com/photos/jschementi/tags/crosscountry/" target="_blank">I’ve moved from Seattle to New York</a>, started my new career at <a href="http://lab49.com/" target="_blank">Lab49</a>, <a href="http://photographybyverdi.com/2010/10/18/the-wedding-of-felicia-and-james/" target="_blank">got married</a>, and just got back from <a href="http://www.flickr.com/photos/jschementi/sets/72157625070175315/" target="_blank">the honeymoon</a>, my public techie life can resume. And I’m happy to resume it on a positive note.</p> <p>Today signifies a big step in Microsoft’s commitment to open-source: <a href="http://blogs.msdn.com/b/jasonz/" target="_blank">Jason Zander</a> <a href="http://blogs.msdn.com/b/jasonz/archive/2010/10/21/new-components-and-contributors-for-ironpython-and-ironruby.aspx" target="_blank">announced new leadership for IronRuby and IronPython</a>, namely <a href="http://tirania.org/blog/" target="_blank">Miguel de Icaza</a>, <a href="http://www.voidspace.org.uk/python/weblog/index.shtml" target="_blank">Michael Foord</a>, <a href="http://jdhardy.blogspot.com/" target="_blank">Jeff Hardy</a>, and <a href="http://blog.jimmy.schementi.com/" target="_blank">myself</a>. Since Microsoft has officially put the project in our hands, both languages will be open to contributions from the community, not just the core team members. Also, any previously unreleased work as been released, include the IronRuby tools for Visual Studio and groundwork towards IronPython 2.7 and 1.9. You can find the appropriate releases on both <a href="http://ironruby.codeplex.com" target="_blank">IronRuby</a> and <a href="http://ironpython.codeplex.com" target="_blank">IronPython</a>’s CodePlex sites.</p> <p>Though Microsoft is no longer directly resourcing these projects, there are definitely companies providing support. <a href="http://lab49.com/">Lab49</a> has been tremendously supportive of my participation in the project, and is interested in supporting the project in substantial ways going forward. Those details will become clearer in the future, but it’s great to see my company taking a proactive role in the projects I’m part of. Also, <a href="http://tirania.org/blog/" target="_blank">Miguel</a> is a big-shot at Novell, but I’ll let him comment on how his company is supporting the projects. =)</p> <p>The reality of open-source software is that corporate sponsorship and funding comes and goes. I'm grateful to Microsoft for starting IronPython and IronRuby, funding it up until this point, and passing the torch to individuals who will continue to progress the languages forward. I’d specifically like to thank Bill Chiles, <a href="http://blogs.msdn.com/b/dinoviehland/" target="_blank">Dino Viehland</a>, and <a href="http://blog.tomasm.net" target="_blank">Tomáš Matoušek</a>, who did the hard work to make this transition happen.</p> <p>If you’re interested in the future of these projects, please subscribe to their mailing lists (<a href="http://ironruby.net/support" target="_blank">IronRuby</a>, <a href="http://ironpython.net/support/" target="_blank">IronPython</a>) and help us to continue making a great dynamic language experience on .NET.</p>
</div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=rudgFi5xxA4:RmY6zEPpuw4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=rudgFi5xxA4:RmY6zEPpuw4:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=rudgFi5xxA4:RmY6zEPpuw4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=rudgFi5xxA4:RmY6zEPpuw4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=rudgFi5xxA4:RmY6zEPpuw4:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=rudgFi5xxA4:RmY6zEPpuw4:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=rudgFi5xxA4:RmY6zEPpuw4:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jimmy-thinking/~4/rudgFi5xxA4" height="1" width="1" alt=""/>Thu, 21 Oct 2010 23:14:00 +0000http://feedproxy.google.com/~r/jimmy-thinking/~3/rudgFi5xxA4/leadership-of-ironruby-and-ironpython.html
http://jimmy.schementi.com/2010/10/leadership-of-ironruby-and-ironpython.htmlhttp://jimmy.schementi.com/2010/10/leadership-of-ironruby-and-ironpython.html“Start spreading the news”: the future of Jimmy and IronRuby<div class="post-content">
<p>Though <a href="http://social.zune.net/bingplayer/?v=1.0#mid=1D5D1B01-0100-11DB-89CA-0019B92A3933&amp;title=New%20York%2C%20New%20York&amp;artist=Frank%20Sinatra&amp;album=New%20York%2C%20New%20York&amp;artistid=4E0C0000-0600-11DB-89CA-0019B92A3933&amp;albumid=FF5C1B01-0100-11DB-89CA-0019B92A3933&amp;dto=1&amp;preview=0&amp;explicit=0&amp;lyrics=">Frank Sinatra</a> <a href="http://www.bing.com/music/lyrics/detail?q=Frank+Sinatra+New+York,+New+York&amp;songID=1D5D1B01-0100-11DB-89CA-0019B92A3933&amp;lyricsID=T+++691568&amp;albumID=FF5C1B01-0100-11DB-89CA-0019B92A3933&amp;FORM=DTPMUM">says it best</a>, “I’m leaving today” isn’t exactly accurate; my last day as a Microsoft employee was July 23rd, 2010. This post is almost two weeks delayed as <a href="http://twitter.com/feliciacutrone" target="_blank">Felicia</a> and I have been on the road since the 26th, driving cross-country to the east coast; we also decided to leave Seattle in favor of New York, our home state.</p> <p>Both decisions were extremely difficult to make, as I will miss all the brilliant people I worked with. Just being in their presence made me feel smarter, and we accomplished some amazing things together. Many were also my friends, making this a very heart-wrenching decision too. However, I joined Microsoft to bring Ruby and other open-source programming languages to the .NET framework, as well as to promote open-source practices in general, and I promised myself to ensure the truth of that statement throughout my Microsoft career. So, when my manager asked me, “what else would you want to work on other than Ruby,” I started looking for a new job outside Microsoft.</p> <p>While Microsoft’s commitment to dynamic languages on .NET has been questioned many times, my tiny team has been excellent at suppressing those fears with quality implementations of <a href="http://ironruby.net" target="_blank">Ruby</a> and <a href="http://ironpython.net" target="_blank">Python</a> for .NET, compiler services and language embedding API called the <a href="http://dlr.codeplex.com" target="_blank">Dynamic Language Runtime</a>, and integration with .NET application frameworks like <a href="http://silverlight.net/dlr" target="_blank">Silverlight</a> and <a href="http://aspnet.codeplex.com/wikipage?title=Dynamic%20Language%20Support" target="_blank">ASP.NET</a>. And most recently the beginnings of <a href="http://ironpython.net/tools/" target="_blank">IDE support for dynamic languages in Visual Studio</a>. And all this released under an well-known open-source license, the <a href="http://www.apache.org/licenses/LICENSE-2.0.html" target="_blank">Apache License (Version 2)</a>. This was only possible because my team had the freedom to do what we needed to do to counter those fears and run an effective open-source project</p> <p>However, a year ago the team shrunk by half and our agility was severely limited. I’m omitting the internal reasons for this, as they are the typical big-company middle-management issues every software developer has. In short, the team is now very limited to do anything new, which is why the Visual Studio support for IronPython took so long. IronRuby’s IDE support in Visual Studio hasn’t been released yet for the same reasons. While this is just one example, many other roadblocks have cropped up that made my job not enjoyable anymore.</p> <p>Overall, I see a serious lack of commitment to IronRuby, and dynamic language on .NET in general. At the time of my leaving <a href="http://blog.tomasm.net/" target="_blank">Tomas</a> and myself were the only Microsoft employees working on IronRuby. If this direction for dynamic languages on .NET is a path you <strong>do not</strong> want Microsoft to take, I strongly suggest you provide feedback to the <a href="http://tinyurl.com/2edqg6t" target="_blank">team’s management</a> directly. Also, <a href="http://blogs.msdn.com/b/jasonz/" target="_blank">Jason Zander</a> runs the Visual Studio team, which IronRuby, IronPython, and the DLR happen to be a part of, and is a big <strong>proponent</strong> of these dynamic languages efforts, so provide him with your thoughts as well.</p> <p>That being said, I am still interested in implementing dynamic languages on .NET, so I will remain a <a href="http://ironruby.net" target="_blank">IronRuby</a> core-team member, ironically making me the first non-Microsoft core contributor. The bad-news is I will no longer be working on IronRuby full-time, but in the near future I’m definitely staying active. Also, Tomas will definitely continue working on IronRuby when he can; we weren’t the last two people left for no reason. :-)</p> <p>Given that Tomas and I will only be working part-time on IronRuby now, I invite the Ruby and .NET communities to come help us figure out how to continue the IronRuby project, assuming that Microsoft will eventually stop funding it. I’ll start a thread on the <a href="http://rubyforge.org/pipermail/ironruby-core/" target="_blank">IronRuby Mailing List</a> shortly, so keep an eye on that if you’d like to help. [<strong>Update</strong>: <a href="http://bit.ly/dBVJSC" target="_blank">here’s the thread about the next steps for IronRuby</a>. <a href="http://bit.ly/aKJz7p" target="_blank">Join the list</a> and discuss.]</p> <p>While moving to New York is mainly a personal decision, as both my fiancée and I grew up there and our immediate families are still there, it was also for professional reasons; I’ve accepted a new position at <a href="http://lab49.com/">Lab49</a>, a financial technology consulting firm in New York City. I chose the financial industry not just because its dominance in New York, but because I see a lot of similarities between financial software and developer tools. Financial software serves a very technical user, much like programmers, but unlike programmers I know nothing these users, making it a challenging new space. It will be familiar as well, as Lab49 has done work with the new <a href="http://www.zdnet.com/blog/microsoft/microsoft-launches-technical-computing-initiative-20/6240" target="_blank">Technical Computing</a> team, which many people who once worked on dynamic languages moved to. Lab49 was also very interested in my IronRuby and IronPython background, so it’s a great next step for me.</p> <p>I’m grateful to have worked on compilers full-time, outside of academia, while still contributing to open-source, especially at a company that hardly showed up on the open-source radar just 4 years ago. And at least one dynamic language at Microsoft is getting love; <a href="http://blogs.msdn.com/b/ie/archive/2010/03/18/the-new-javascript-engine-in-internet-explorer-9.aspx" target="_blank">IE9’s JavaScript engine</a>, and Microsoft has awesome intentions with it. I’m totally a supporter of most things Microsoft is doing, and I look forward to working closely with them on financial problems. I’m just extremely disappointed with their decisions around dynamic languages on .NET. As one former-teammate’s email signature read, “If your ideas are any good, you'll have to ram them down people's throats.”</p> <p>I’m looking forward to this new chapter in both my life and my career. Not only am I living in the <a href="http://en.wikipedia.org/wiki/New_York_City" target="_blank">city that never sleeps</a>, but I hope to build upon my dynamic language work and use it in an area completely new to me. While I expect to still be Ruby and .NET oriented, my posts will be about solving new problems, and should make for some good reading. Stay tuned, and thanks for all the support thus far.</p>
</div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=ZfPYAr28WfY:jQFv18pv9dk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=ZfPYAr28WfY:jQFv18pv9dk:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=ZfPYAr28WfY:jQFv18pv9dk:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=ZfPYAr28WfY:jQFv18pv9dk:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=ZfPYAr28WfY:jQFv18pv9dk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=ZfPYAr28WfY:jQFv18pv9dk:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=ZfPYAr28WfY:jQFv18pv9dk:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jimmy-thinking/~4/ZfPYAr28WfY" height="1" width="1" alt=""/>Fri, 06 Aug 2010 21:40:00 +0000http://feedproxy.google.com/~r/jimmy-thinking/~3/ZfPYAr28WfY/start-spreading-news-future-of-jimmy.html
http://jimmy.schementi.com/2010/08/start-spreading-news-future-of-jimmy.htmlhttp://jimmy.schementi.com/2010/08/start-spreading-news-future-of-jimmy.htmlASP.NET dynamic language support is open source<div class="post-content">
<p>I'm happy to <i>finally </i>announce that the <b><a href="http://ironpython.net/download/aspnet-20100716" target="_blank">ASP.NET dynamic language support</a></b> is now <b><a href="http://www.apache.org/licenses/LICENSE-2.0.html" target="_blank">open source</a></b>: </p> <p><a href="http://ironpython.net/download/aspnet-20100716" target="_blank"><strong>Download IronPython and ASP.NET integration</strong></a></p> <p><em>For a full <a href="http://ironpython.net" target="_blank">IronPython</a> release with the Python standard library, download </em><a href="http://ironpython.codeplex.com/releases/view/42434" target="_blank"><em>IronPython 2.7 Alpha 1</em></a><em>.</em></p> <p>This release contains the source code to <code>Microsoft.Scripting.AspNet.dll</code>, located in the <code>src</code> directory, licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0.html" target="_blank">Apache License (Version 2)</a>. It will be available in the source repository for IronPython in the very near future, but don't hesitate to start <a href="http://ironpython.codeplex.com/SourceControl/UploadPatch.aspx" target="_blank">sending in patches</a>. This release is compatible with <a href="http://ironpython.codeplex.com/releases/view/42434" target="_blank">IronPython 2.7 Alpha 1</a>.</p> <h4>Background</h4> <p>This download enables <a href="http://www.asp.net/dynamiclanguages" target="_blank">IronPython as an ASP.NET programming language</a>. To create a new IronPython ASP.NET WebForms project, simply copy <code>examples\web.config</code> and <code>examples\bin</code>, and use <code>examples\hello-webforms.aspx</code> as a reference. A redistributed copy of the IronPython 2.7 Alpha 1 binaries can be found in the <code>examples\bin</code> directory; all files except <code>Microsoft.Scripting.AspNet.dll</code>, the IronPython ASP.NET integration, are from the IronPython 2.7 Alpha 1 release.</p> <p>For more detail on getting started, <a href="http://blog.jimmy.schementi.com/2008/09/aspnet-dynamic-language-support.html" target="_blank">here’s a simple walk-through of making the “hello-webforms” app</a>.</p> <h4>Package</h4> <p>Here's what's in the zip file:</p> <ul> <li><code>/License.html</code> - The Apache License, Version 2. </li> <li><code>/dlr-aspnet.sln</code> - VS2010 solution for examples </li> <li><code>/examples</code> - Examples of using IronPython in ASP.NET. </li> <li><code>/examples/Web*.config</code> - configures ASP.NET to use IronPython </li> <li><code>/examples/bin</code> - Microsoft.Scripting.AspNet.dll, the ASP.NET integration, and a redistribution of IronPython 2.7A1. </li> <li><code>/src</code> - C# source code that builds Microsoft.Scripting.AspNet.dll </li> </ul> <h4>Upgrading</h4> <p>This release renames the main DLL from <code>Microsoft.Web.Scripting.dll</code> to <code>Microsoft.Scripting.AspNet.dll</code>. If upgrading, you'll have to replace all occurrences of <code>Microsoft.Web.Scripting</code> with <code>Microsoft.Scripting.AspNet</code>. This will primarily be at the top of all aspx pages, as well as in your application's web.config. Also note the version number is now 1.1.0.1, which matches all the other <code>Microsoft.Scripting</code> assemblies.</p> <h4>Feedback</h4> <p>As always, please report issues on the <a href="http://ironpython.codeplex.com/WorkItem/Create" target="_blank">IronPython issue tracker</a>. You can also try to fix any issues yourself and <a href="http://ironpython.codeplex.com/SourceControl/UploadPatch.aspx" target="_blank">submit a patch</a>. Lastly, you can actually talk to humans on the <a href="http://lists.ironpython.com/listinfo.cgi/users-ironpython.com" target="_blank">IronPython mailing list</a>.</p> <h4>Enjoy!</h4>
</div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=LXR49z688UQ:gks3PmIeNks:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=LXR49z688UQ:gks3PmIeNks:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=LXR49z688UQ:gks3PmIeNks:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=LXR49z688UQ:gks3PmIeNks:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=LXR49z688UQ:gks3PmIeNks:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=LXR49z688UQ:gks3PmIeNks:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=LXR49z688UQ:gks3PmIeNks:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jimmy-thinking/~4/LXR49z688UQ" height="1" width="1" alt=""/>Mon, 26 Jul 2010 07:07:00 +0000http://feedproxy.google.com/~r/jimmy-thinking/~3/LXR49z688UQ/aspnet-dynamic-language-support-is-open.html
http://jimmy.schementi.com/2010/07/aspnet-dynamic-language-support-is-open.htmlhttp://jimmy.schementi.com/2010/07/aspnet-dynamic-language-support-is-open.htmlSummer of “Iron”: LINQ, Visual Studio tooling, and the Apache License<div class="post-content">
<p>New releases and announcements from the “Iron” projects have come out over the last couple days, so I wanted to give you an overview of what’s happening, point out the really cool parts, and reiterate some of the motivations.</p> <p>From a release perspective, both IronRuby and IronPython released new versions of the DLR-based .NET programming language implementations: <a href="http://ironpython.codeplex.com/releases/view/42434" target="_blank">IronPython 2.7 Alpha</a> and <a href="http://ironruby.codeplex.com/releases/view/43540" target="_blank">IronRuby 1.1</a>. Click on the respective release name for the full release notes and downloads, but I’ll summarize a bit here:</p> <h4>IronPython 2.7 Alpha</h4> <p><a href="http://ironpython.codeplex.com/releases/view/42434" target="_blank">Install IronPython 2.7 Alpha</a> (includes <a href="http://ironpython.net/tools/" target="_blank">Visual Studio tooling</a>)</p> <p>This Alpha release is the first IronPython release working towards Python 2.7 compatibility, and contains a number of bug fixes and performance improvements. It also now <strong>requires</strong> .NET 4.0 or Silverlight 4; you will need to <a href="http://ironpython.codeplex.com/SourceControl/list/changesets" target="_blank">build from source</a> for down-level frameworks. The installer now includes Visual Studio support for IronPython, rather than being a separate installer, and the source-code for the tools has been open-sourced! Keep reading for licensing information …</p> <h4>IronRuby 1.1</h4> <p><a href="http://ironruby.codeplex.com/releases/view/43540" target="_blank">Install IronRuby 1.1</a></p> <p>Aside from a bunch of bug-fixes, the latest release of IronRuby adds support for .NET extension methods, meaning that .NET programming patterns that are dependent on extension methods, like LINQ, the Reactive framework, Parallel.NET, etc, are now all usable from Ruby code. For example, here’s a simple LINQ example:</p> <script src="http://gist.github.com/482344.js?file=linq.rb"></script> <p>For more information see the <a href="http://github.com/ironruby/ironruby/blob/master/Languages/Ruby/Samples/Linq/101samples.rb" target="_blank">101 LINQ samples ported to IronRuby</a>.</p> <p>Also, since I never <a href="http://ironruby.codeplex.com/releases/view/25901" target="_blank">announced the IronRuby 1.0 release</a> on my blog … consider this the announcement.</p> <h4>Apache License, Version 2</h4> <p><a href="http://ironruby.codeplex.com/license" target="_blank">IronRuby</a>, <a href="http://ironpython.codeplex.com/license" target="_blank">IronPython</a>, and the <a href="http://dlr.codeplex.com/license" target="_blank">DLR</a> are now licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0.html" target="_blank">Apache License, Version 2</a>. To address all concerns around <em>“why”</em> this is changing, it is <strong>solely</strong> in reaction to feedback about the licensing terms from users and the .NET/Python/Ruby/dynamic-language communities at-large. The Apache License is a more familiar and popular license to those communities than the Microsoft Public License; using it should lower any license-related barriers people encountered in the past when considering these programming-language implementations.</p> <h4>Enjoy!</h4>
</div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=Ct4ixXU6VDw:kuPb2cEHQ4Q:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=Ct4ixXU6VDw:kuPb2cEHQ4Q:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=Ct4ixXU6VDw:kuPb2cEHQ4Q:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=Ct4ixXU6VDw:kuPb2cEHQ4Q:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=Ct4ixXU6VDw:kuPb2cEHQ4Q:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=Ct4ixXU6VDw:kuPb2cEHQ4Q:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=Ct4ixXU6VDw:kuPb2cEHQ4Q:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jimmy-thinking/~4/Ct4ixXU6VDw" height="1" width="1" alt=""/>Tue, 20 Jul 2010 03:05:00 +0000http://feedproxy.google.com/~r/jimmy-thinking/~3/Ct4ixXU6VDw/summer-of-iron-linq-visual-studio.html
http://jimmy.schementi.com/2010/07/summer-of-iron-linq-visual-studio.htmlhttp://jimmy.schementi.com/2010/07/summer-of-iron-linq-visual-studio.htmlMIX10, Part 3 - Using dynamic languages in existing web-applications<div class="post-content">
<div style="border-bottom: #666 5px solid; border-left: #666 5px solid; padding-bottom: 5px; background-color: #333; margin: 0px 0px 10px; padding-left: 5px; padding-right: 5px; color: white; border-top: #666 5px solid; border-right: #666 5px solid; padding-top: 5px"> <p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" class="section"><em>This post is part of the “MIX10 – Pumping Iron on the web” series:</em></p> <ul style="padding-bottom: 0px; margin: 0px 0px 0px 20px; padding-left: 0px; padding-right: 0px; padding-top: 0px"> <li><a href="http://blog.jimmy.schementi.com/2010/03/mix10-ironruby-and-ironpython-part-1.html">Part 1 - Introduction</a> </li> <li><a href="http://blog.jimmy.schementi.com/2010/04/mix10-part-21-server-side-web.html">Part 2.1 – Server-side web development with dynamic languages</a> </li> <li><a href="http://blog.jimmy.schementi.com/2010/04/mix10-part-22-client-side-web.html">Part 2.2 – Client-side web development with dynamic languages</a> </li> <li><strong>Part 3 - Using scripting in static applications </strong></li> <li><em>Coming soon: </em>Part 4 - Web-app extensibility with scripts </li> </ul> </div> <blockquote> <p><em>The original post was mistakenly removed, so it’s been reposted with the original post date, 4/27/2010. Sorry if this confuses your blog readers or causes any other inconvenience.</em></p> </blockquote> <p>Up until now I've discussed how to use dynamic languages to power both the server-side as well as the client-side of your web-application, but what if you want to apply these methods to solve certain problems in an existing application?</p> <h4><font color="#ff8000"><strong>Testing</strong></font></h4> <p>A low-risk, high-benefit use of dynamic languages in your existing applications is for testing. This helps make the act of writing tests simpler, and quite possibly more fun, encouraging your team to actually maintain the test suite.</p> <p>Before looking at how to test web-apps, let's take a brief look at what a test written with <a href="http://rspec.info/" target="_blank">RSpec</a>, a popular Ruby testing framework, looks like:</p> <script src="http://gist.github.com/481156.js?file=rspec.rb"></script> <blockquote> <p><strong>Note</strong>: there are Ruby testing frameworks that look a bit more like what you might be used to. The following is an equivalent test written with test/unit, and this will give you a better idea of the structure of the above example:</p> <script src="http://gist.github.com/481156.js?file=testunit.rb"></script></blockquote> <p>The RSpec snippet almost reads like english, making it very clear what the intended behavior of Stack is. Also, it shows the power of Ruby for creating internal DSLs; a &quot;language&quot; built out of the constructs of an existing language. <code>describe</code> and <code>it</code> look like language keywords, but in-fact they are really just methods, because Ruby has optional parameters (<a href="http://blog.jimmy.schementi.com/2010/04/mix10-part-21-server-side-web.html" target="_blank">as we discovered earlier with Sinatra</a>). Using actual strings as the test name, rather than a method name, allows you to describe the test accurately. Each object has a <code>should</code> method which makes any subsequent calls part of an assertion, making it very obvious which value is the &quot;expected&quot; value and which is the &quot;actual&quot;.</p> <p>The crazy thing is how little code is required to make that work; <strong><font color="#ff8000">24 lines of Ruby</font></strong>. The key points are that <code>yield</code> executes the <code>do-end</code> block passed to a method, and the <code>should</code> method is added to every object, turning any subsequent methods calls into an assertion:</p> <script src="http://gist.github.com/481156.js?file=test-spec.rb"></script> <p>However, please don't use this example as your real testing framework, and then get mad at me when it doesn't have a feature you want; <a href="http://rspec.info/" target="_blank">RSpec</a>, <a href="http://github.com/chneukirchen/bacon" target="_blank">Bacon</a>, or <a href="http://test-spec.rubyforge.org" target="_blank">test/spec</a> are much more mature testing frameworks that support this same syntax.</p> <p><a href="http://blog.jimmy.schementi.com/2009/03/testing-c-silverlight-apps-with.html" target="_blank">See my previous post about using IronRuby to test C# Silverlight applications</a>; it’s still relevant though it’s a fairly old post.</p> <h4><strong><font color="#ff8000">Hosting</font></strong></h4> <p>IronRuby and IronPython are built on-top of the <a href="http://dlr.codeplex.com" target="_blank">Dynamic Language Runtime</a>, which is comprised of many parts, one of which being a <strong><a href="http://dlr.codeplex.com/Project/Download/FileDownload.aspx?DownloadId=127516" target="_blank">.NET Hosting API</a></strong>, allowing you to embed a scripting language in any .NET app.</p> <p><font color="#ff8000"><strong>Now we come to the &quot;ah-ha!&quot; moment of the talk</strong></font>; <strong>everything</strong> you've seen in the <a href="http://blog.jimmy.schementi.com/search/label/MIX10" target="_blank">MIX10 posts</a> is made possible by this API. Keep in mind these languages are built <em>on</em> .NET, so their implementations are accessible from any .NET language. C# and VB today are not built on .NET; they just compile programs to run on .NET, which is why you can't easily host those languages today.</p> <p>Here's the catch; since these language engines are built on .NET, they need to run <em>in</em> a .NET application. So, <strong>all</strong> Ruby or Python code runs by hosting the languages inside a .NET application. We do things to make this seamless in specific environments: for example, <tt>ir.exe</tt> and <tt>ipy.exe</tt> are both .NET programs which host the language and run the code in a command-line, mimicking the behavior of ruby.exe and python.exe. Here are some other popular hosts:</p> <ul> <li><tt>ipyw.exe</tt>: runs scripts in a console-less program for Windows applications </li> <li><tt>Microsoft.Scripting.Silverlight.dll</tt>: entry-point for Silverlight applications which run HTML script tags and scripts inside the XAP </li> <li><tt>IronRuby.Rack.dll</tt>: run rack-based applications on IIS </li> <li><tt>Microsoft.Web.Scripting.dll</tt>: run Python in ASP.NET </li> <li><tt>System.Web.Mvc.IronRuby</tt>: run Ruby in ASP.NET MVC </li> </ul> <p>However, we can't provide &quot;runners&quot; for every environment that will spring up, so we allow you to use the same APIs that these runners use in your own apps. These APIs have been kept very simple, as we want any .NET developer to be able to use a DLR scripting language in their applications.</p> <p><strong><font color="#ff8000">But why embed a scripting language into your application?</font></strong> The main scenario is to scripts as an extensibility mechanism, either internally or as functionality you provide for your end-users. Here are a few concrete examples of what scripts could be used for:</p> <ul> <li>An advanced search/filter (letting users use LINQ safely) </li> <li>High-level business logic to computing prices of items, applying discounts, etc; any type of rules engine </li> <li>A system which changes behavior based on external data </li> <li>Customizing a single codebase for different clients </li> <li>Add-ons for end-users to make your application better (eg. Facebook) </li> <li>Making application logic simpler to read than the core of your system (polyglot) </li> </ul> <p>Let's show you how to do the basics, and hopefully that will spark your imagine to think up other cool use-cases:</p> <ol> <li>Create a new web application project in Visual Studio 2010, and open the Default.aspx.cs page. </li> <li>Place a label on the page and call it “Message”. </li> <li>Add references to the necessary DLLs to host IronPython (IronPython.dll and Microsoft.Scripting.dll) </li> <li>Write the 5 lines of code to update the label’s text from Python: </li> </ol> <script src="http://gist.github.com/481156.js?file=hosting.cs"></script> <p>There are basically three types you need to know; <code>ScriptRuntime</code>, <code>ScriptEngine</code>, and <code>ScriptScope</code>.</p> <ul> <li> <p><code>ScriptRuntime</code> is a level of encapsulation for your scripts; it represents the DLR scripting runtime, and all script operations go through it.</p> </li> <li> <p><code>ScriptEngine</code> is the type that is returned from <code>ScriptRuntime.GetEngine</code>; it represents a DLR-language. In this case, we asked for the language by name, as that's the easiest way to keep it easily configurable, but the downside is you need language configuration info in your <code>App.config</code>. However, if you only want to depend on IronPython, you can use <code>IronPython.Hosting.Python.CreateEngine()</code>, which does all the setup for Python for you.</p> <p>The <code>ScriptEngine</code> enabled you to execute code in that language, in a variety of ways, from the basic <code>engine.Execute</code> method (essentally <code>eval</code>), or being more fine-grained <code>engine.CreateScriptSourceFromString(code).Compile().Execute()</code>, which parses the file, compiles it, and then executes it. Code can be executed against a <code>ScriptScope</code> to set initial state and share state between executions.</p> </li> <li> <p><code>ScriptScope</code> defines the state for your script; like what variables/methods are present. It is a dynamic object, so you can do things like <code>scope.page = this</code>, and that will set the <code>page</code> variable for scripts that execute against the scope. In downlevel .NET frameworks, you'd have to use <code>scope.SetVariable(page, this)</code>.</p> </li> </ul> <p><em>Slight aside</em>: since these APIs are .NET based, the dynamic languages themselves can consume them to run other dynamic languages! For example, here's Ruby executing Python code through the <a href="http://dlr.codeplex.com" target="_blank">DLR</a> Hosting APIs:</p> <script src="http://gist.github.com/481156.js?file=ruby-host-python.rb"></script> <p>What's also interesting is the dynamic languages can communicate between <strong>each-other</strong> just as easily; here's Ruby calling Python code:</p> <script src="http://gist.github.com/481156.js?file=foo.py"></script><script src="http://gist.github.com/481156.js?file=bar.rb"></script> <p>Anyway, hopefully this sparks some creativity! For more web-related information, also posted about this in relation to Silverlight applications: <a href="http://blog.jimmy.schementi.com/2009/03/scripting-c-silverlight-apps-with.html" target="_blank">Scripting C# apps with IronPython</a>.</p> <p>The next post will show some cool applications of this … (<em>coming soon</em>).</p>
</div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=dzJKI3qRc6o:VJ3h-e4SFJI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=dzJKI3qRc6o:VJ3h-e4SFJI:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=dzJKI3qRc6o:VJ3h-e4SFJI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=dzJKI3qRc6o:VJ3h-e4SFJI:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=dzJKI3qRc6o:VJ3h-e4SFJI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=dzJKI3qRc6o:VJ3h-e4SFJI:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=dzJKI3qRc6o:VJ3h-e4SFJI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jimmy-thinking/~4/dzJKI3qRc6o" height="1" width="1" alt=""/>Tue, 27 Apr 2010 10:19:00 +0000http://feedproxy.google.com/~r/jimmy-thinking/~3/dzJKI3qRc6o/mix10-part-3-using-dynamic-languages-in.html
http://jimmy.schementi.com/2010/04/mix10-part-3-using-dynamic-languages-in.htmlhttp://jimmy.schementi.com/2010/04/mix10-part-3-using-dynamic-languages-in.htmlMIX10, Part 2.2 – Client-side web-development with dynamic languages<div class="post-content">
<div style="border-bottom: #666 5px solid; border-left: #666 5px solid; padding-bottom: 5px; background-color: #333; margin: 0px 0px 10px; padding-left: 5px; padding-right: 5px; color: white; border-top: #666 5px solid; border-right: #666 5px solid; padding-top: 5px"> <p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" class="section"><em>This post is part of the “MIX10 – Pumping Iron on the web” series:</em></p> <ul style="padding-bottom: 0px; margin: 0px 0px 0px 20px; padding-left: 0px; padding-right: 0px; padding-top: 0px"> <li><a href="http://blog.jimmy.schementi.com/2010/03/mix10-ironruby-and-ironpython-part-1.html">Part 1 - Introduction</a> </li> <li><a href="http://blog.jimmy.schementi.com/2010/04/mix10-part-21-server-side-web.html">Part 2.1 – Server-side web development with dynamic languages</a> </li> <li><strong>Part 2.2 – Client-side web development with dynamic languages</strong> </li> <li><a href="http://blog.jimmy.schementi.com/2010/04/mix10-part-3-using-dynamic-languages-in.html">Part 3 - Using scripting in static applications</a> </li> <li><em>Coming soon: </em>Part 4 - Web-app extensibility with scripts </li> </ul> </div> <blockquote> <p><em>The original post was mistakenly removed, so it’s been reposted with the original post date, 4/26/2010. Sorry if this confuses your blog readers or causes any other inconvenience.</em></p> </blockquote> <p><font color="#ff8000"><strong></strong></font></p> <p><a href="http://ironruby.net" target="_blank">IronRuby</a> and <a href="http://ironpython.net" target="_blank">IronPython</a> are fully-supported in the browser, thanks to <a href="http://silverlight.net" target="_blank">Silverlight</a>. In-fact, they are hands-down the simplest way to develop a Silverlight application. This is not only because of how expressive the programming languages are; the integration with Silverlight doesn't fight how the web works.</p> <p>For example, here's an entire Silverlight app which just writes a message into the HTML page, written in Python:</p> <script src="http://gist.github.com/318169.js?file=helloworld.html"></script> <p>DLR-based Silverlight applications let you write HTML script-tags in other languages than JavaScript, but in a way that works cross-browser and cross-platform; the languages work in <a href="http://www.go-mono.com/moonlight/" target="_blank">Moonlight</a> on Linux as well.</p> <p>Both inline and script-src tags are supported, so your scripts can be separated from the HTML file:</p> <script src="http://gist.github.com/481156.js?file=scripttag_ruby.html"></script> <p>This integration makes writing Silverlight applications just as easy as they were in Silverlight 1, but with the power of .NET and Ruby or Python. <a href="http://dlr.codeplex.com" target="_blank">DLR</a>-based applications also support a XAP model for anyone familiar with how static Silverlight applications work, so you get to choose which way you prefer to write your applications.</p> <p>All the specific examples used in this section of the talk were taken from these posts:</p> <ul> <li><a href="http://blog.jimmy.schementi.com/2010/03/pycon-2010-python-in-browser.html" target="_blank">Python in the browser</a>: my blog post from PyCon 2010 about IronPython in Silverlight </li> <li><a href="http://www.rubyinside.com/ironruby-silverlight-ruby-in-browser-3192.html" target="_blank">Ruby in the browser</a>: my article in <a href="http://rubyinside.com" target="_blank">RubyInside</a> about IronRuby in Silverlight </li> <li><a href="http://silverlight.net/dlr" target="_blank">Silverlight.net / d</a><a href="http://silverlight.net/dlr" target="_blank">ynamic languages</a></a>: tons of info on getting started with Python, Ruby, and the DLR in Silverlight. </li> </ul> <p><font size="2">Next up, <a href="http://blog.jimmy.schementi.com/2010/04/mix10-part-3-using-dynamic-languages-in.html">using dynamic languages in your existing web-applications</a>.</font></p>
</div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=xM9KGofY0mk:5_fdDrL-QCc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=xM9KGofY0mk:5_fdDrL-QCc:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=xM9KGofY0mk:5_fdDrL-QCc:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=xM9KGofY0mk:5_fdDrL-QCc:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=xM9KGofY0mk:5_fdDrL-QCc:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=xM9KGofY0mk:5_fdDrL-QCc:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=xM9KGofY0mk:5_fdDrL-QCc:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jimmy-thinking/~4/xM9KGofY0mk" height="1" width="1" alt=""/>Mon, 26 Apr 2010 10:18:00 +0000http://feedproxy.google.com/~r/jimmy-thinking/~3/xM9KGofY0mk/mix10-part-22-client-side-web.html
http://jimmy.schementi.com/2010/04/mix10-part-22-client-side-web.htmlhttp://jimmy.schementi.com/2010/04/mix10-part-22-client-side-web.htmlMIX10, Part 2.1 – Server-side web development with dynamic languages<div class="post-content">
<div style="border-bottom: #666 5px solid; border-left: #666 5px solid; padding-bottom: 5px; background-color: #333; margin: 0px 0px 10px; padding-left: 5px; padding-right: 5px; color: white; border-top: #666 5px solid; border-right: #666 5px solid; padding-top: 5px"> <p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" class="section"><em>This post is part of the “MIX10 – Pumping Iron on the web” series:</em></p> <ul style="padding-bottom: 0px; margin: 0px 0px 0px 20px; padding-left: 0px; padding-right: 0px; padding-top: 0px"> <li><a href="http://blog.jimmy.schementi.com/2010/03/mix10-ironruby-and-ironpython-part-1.html">Part 1 - Introduction</a> </li> <li><strong>Part 2.1 – Server-side web development with dynamic languages </strong></li> <li><a href="http://blog.jimmy.schementi.com/2010/04/mix10-part-22-client-side-web.html">Part 2.2 – Client-side web development with dynamic languages</a> </li> <li><a href="http://blog.jimmy.schementi.com/2010/04/mix10-part-3-using-dynamic-languages-in.html">Part 3 - Using scripting in static applications</a></li> <li><em>Coming soon: </em>Part 4 - Web-app extensibility with scripts </li> </ul> </div> <blockquote> <p><em>The original post was mistakenly removed, so it’s been reposted with the original post date, 4/25/2010. Sorry if this confuses your blog readers or causes any other inconvenience.</em></p> </blockquote> <p>One reason for embracing dynamic languages is to make your entire web-development experience simpler, be it on <a href="http://asp.net" target="_blank">ASP.NET</a> enabled web-servers, or on the client through <a href="http://silverlight.net" target="_blank">Silverlight</a>. Let's first look at the server.</p> <p>Both <a href="http://ironpython.net" target="_blank">IronPython</a> and <a href="http://ironruby.net" target="_blank">IronRuby</a> can run on the same infrastructure as your ASP.NET applications, though in their own ways. Due to historic reasons, IronPython is supported as an ASP.NET language through the <a href="http://aspnet.codeplex.com/wikipage?title=Dynamic%20Language%20Support&amp;referringTitle=Home" target="_blank">ASP.NET Dynamic Language integration</a>, and IronRuby is supported through <a href="http://www.ruby-forum.com/topic/212515" target="_blank">IronRuby.Rack</a>, which enables <a href="http://rack.rubyforge.org/" target="_blank">Rack</a>-based Ruby web-applications to run on ASP.NET. However, both are open-source, so each one could be ported to the other language.</p> <p>Since these <a href="http://dlr.codeplex.com" target="_blank">DLR</a>-based languages run on ASP.NET, deploying them is no different than any other ASP.NET application; they can be run on any ASP.NET enabled web-server like <a href="http://www.iis.net/" target="_blank">IIS</a>. Keeping that in mind, let’s first look at how simple Ruby web apps can be.</p> <h4><font color="#ff8000"><strong>Minimal Ruby web-applications</strong></font></h4> <h5><a href="http://www.sinatrarb.com/" target="_blank"><img style="display: inline" title="Slide34" alt="Slide34" src="http://lh5.ggpht.com/_OqCZhp9yI0Q/TEQIcG9AmwI/AAAAAAAAAWg/m07YG790GLk/Slide345.jpg?imgmax=800" width="400" height="300" /></a> </h5> <p>Ruby itself has very expressive syntax, and the Ruby community has built many web-frameworks to make web-development really simple. For example, Sinatra is a web-framework made to minimize the amount of code required to respond to web requests:</p> <script src="http://gist.github.com/481096.js?file=helloworld-simple.rb"></script> <p>The above code does exactly what it says; when a get request happens for <code>'/'</code>, show &quot;Hello, World&quot; on the page. This highlights Ruby's domain-specific language abilities; <code>get</code> looks like a keyword, though it's really just a method call with <code>'/'</code> as the first argument (Ruby lets you omit parenthesis from method calls too ... any VB script fans out there?). The <code>do-end</code> block is syntactic sugar for passing a lambda as the last-argument to the <code>get</code> method; all Ruby methods take an arbitrary &quot;block&quot; of code between <code>do</code>-<code>end</code> or <code>{}</code>. Inside that block is what happens on each request, and whatever is returned is written to the response (<code>&quot;Hello, World&quot;</code>); the last statement of any expression (blocks, methods, if-statements, etc) is implicitly the return value of the statement.</p> <blockquote> <p>For all those C# fans, you can use curly-braces too:</p> <script src="http://gist.github.com/481096.js?file=helloworld-curly.rb"></script></blockquote> <p>Though these features sound arbitrary by themselves, if I were to write this with only the more-familiar language features found in Ruby, it would lose its character:</p> <script src="http://gist.github.com/481096.js?file=helloworld-verbose.rb"></script> <p>This defines a Ruby method <code>verbose</code>, which explicitly returns the string &quot;Hello, World&quot;, and then calls the get method directly with the first argument being the URL and the second argument being an explicit pointer to the <code>verbose</code> method. Why does this look so much uglier? While this might be closer to how the programming language actually runs the initial examples, it's not how the programmer thinks.</p> <p>Not to leave Python out of this love-fest, Python can make this look very pretty as well, but in her own special way. Imagining that a Sinatra-like library exists for Python:</p> <script src="http://gist.github.com/481096.js?file=helloworld.py"></script> <p>Here the <code>index</code> method is created, which explicitly accepts both the request and the response as arguments; Python's all about being explicit, while Ruby is very implicit. Then the method would be &quot;decorated&quot; with the <code>sinatra.get</code> decorator, which would tell the web-framework that <code>index</code> represents a get-request for &quot;/&quot;.</p> <blockquote> <h5><font color="#ff8000"><strong>What's a decorator?</strong></font></h5> <p>A <a href="http://www.python.org/dev/peps/pep-0318/" target="_blank">Python decorator</a> is basically a function that accepts a function and returns a function, so this imaginary Sinatra-like framework would define <code>get</code> something like this:</p> <script src="http://gist.github.com/481096.js?file=sinatra.get.py"></script> <p>Another way of looking at it is without the decorator syntax:</p> <script src="http://gist.github.com/481096.js?file=helloworld-verbose.py"></script> <p>It’s a bit more readable than Ruby, and almost equivalent to the decorator way, except for the order of <code>get</code> in the code. You'll also see that getting a method pointer is much cleaner than Ruby (<code>index</code> vs. <code>method(:index)</code>); in Ruby <code>index</code> would call the method, since Ruby allows method calls with or without parenthesis, where Python uses parenthesis to indicate a method call.</p> </blockquote> <p>Point being is that both Ruby and Python are very expressive in their own ways, and makes it really easy to make simple websites on Windows. The IronRuby team takes of advantage of this to power <a href="http://ironruby.info" target="_blank">http://ironruby.info</a>, a Ruby-compatibility reporting website. This is the code from the <a href="http://github.com/jschementi/ironruby-stats/blob/master/app.rb#L83" target="_blank">main page</a>:</p> <script src="http://gist.github.com/481096.js?file=sinatra-haml.rb"></script> <p>This renders the <a href="http://github.com/jschementi/ironruby-stats/blob/master/views/index.haml" target="_blank">index.haml</a> template with the data returned from <code>Stats.get_latest</code>, which is pretty much what the code says. The HTML is generated from the <a href="http://haml-lang.com/" target="_blank">haml templating engine</a>, which makes generating HTML and calling Ruby code extremely easy:</p> <script src="http://gist.github.com/481096.js?file=index.haml"></script> <p>To play around with using HAML, you can use <a href="http://github.com/jschementi/orphanage/tree/master/aspnet-haml/" target="_blank">aspnet-haml</a> to support .haml files though ASP.NET.</p> <h4><strong><font color="#ff8000">Ruby on Rails - Databases with Ruby</font></strong></h4> <p><a href="http://rubyonrails.org" target="_blank"><img style="display: inline" title="Slide45" alt="Slide45" src="http://lh3.ggpht.com/_OqCZhp9yI0Q/TEQIcsQcBUI/AAAAAAAAAWk/HjDOc25xSdU/Slide45%5B6%5D.jpg?imgmax=800" width="400" height="300" /></a> </p> <p>One of the most popular (or most buzzed) web-frameworks is <a href="http://rubyonrails.org/" target="_blank">Ruby on Rails</a>, which is just a collection of Ruby libraries for structuring your web-application. Rails uses the <a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller" target="_blank">Model-View-Controller pattern</a>, so any <a href="http://www.asp.net/mvc" target="_blank">ASP.NET MVC</a> people will find it a very-familiar framework. However, Rails really shines when it comes to interacting with the database through it's ActiveRecord library (the “Model” layer). ActiveRecord maps Ruby classes to database tables, and provides an Ruby abstraction for interacting with the database:</p> <script src="http://gist.github.com/481096.js?file=rails-example.rb"></script> <p>This is all the code that is required to map your Ruby classes to the database, as well as create the structure of the database. ActiveRecord dynamically provides getters/setters for the table, as well as sets up foreign-keys and relationships based on conventions (belongs_to :posts assumes that the table has a 'post_id' field).</p> <p>Interacting with the database is just as easy as calling methods; <code>Post.all</code> translates to the <code>SELECT * from posts</code> SQL query, since the <code>Post</code> object is mapped to the <code>posts</code> database table. <code>Post.find(&lt;id&gt;)</code> does a <code>SELECT * from posts where id=&lt;id&gt;</code>, etc.</p> <p>Because Rails uses the <a href="http://rack.rubyforge.org/" target="_blank">Rack web-server interface</a>, it will also run on IIS using <a href="http://www.ruby-forum.com/topic/212515" target="_blank">IronRuby.Rack</a>. See <a href="http://ironruby.net/documentation/rails" target="_blank">the IronRuby Rails documentation</a> for more info about using Rails on IronRuby, and the <a href="http://api.rubyonrails.org" target="_blank">Ruby on Rails documentation</a> for general Rails usage.</p> <h4><strong><font color="#ff8000">ASP.NET MVC and IronRuby</font></strong></h4> <p>Those were all Ruby-based web-frameworks, but what about using ASP.NET directly? The IronRuby community has developed an <a href="http://github.com/casualjim/ironrubymvc" target="_blank">integration with ASP.NET MVC</a>, so you can write your controllers and views in Ruby. Special thanks to <a href="http://flanders.co.nz/" target="_blank">Ivan Porto Carrero</a> for single-handedly maintaining it.</p> <h4><strong><font color="#ff8000">ASP.NET and IronPython</font></strong></h4> <p>Again, to give Python some love, <a href="http://aspnet.codeplex.com/wikipage?title=Dynamic%20Language%20Support" target="_blank">IronPython directly integrates with ASP.NET</a>, letting you write your ASPX code-behind files in Python.</p> <script src="http://gist.github.com/481133.js?file=hello-webforms.aspx"></script><script src="http://gist.github.com/481133.js?file=hello-webforms.aspx.py"></script> <p>Because of ASP.NET's events-based API (rather than a response-based API like Sinatra/Rails), Python methods can automatically hook events by using the &lt;object&gt;_&lt;event-name&gt; convention, and all server-side controls with &quot;ID&quot;s ends up being a variable available to the Python module. And application-level event hooks can go in global.py. But it's really nice to write Language=&quot;IronPython&quot; at the top. =)</p> <p>Python code can can also interact with the controls:</p> <script src="http://gist.github.com/481133.js?file=python-controls.aspx"></script> <p>The &lt;%# %&gt; syntax lets run Python code in the context of the ASP.NET control's data source. The repeater's data-source was set to a list of IMAGETAGS (a python class), which has all those fields on it.</p> <p>In conclusion, on the server you have many options for using IronRuby and IronPython to simplify your solutions.</p> <p>Next up, <a href="http://blog.jimmy.schementi.com/2010/04/mix10-part-22-client-side-web.html">using dynamic languages on the client through Silverlight</a>.</p>
</div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=dbvrjAopSWA:Hu8lgyLpn8g:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=dbvrjAopSWA:Hu8lgyLpn8g:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=dbvrjAopSWA:Hu8lgyLpn8g:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=dbvrjAopSWA:Hu8lgyLpn8g:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=dbvrjAopSWA:Hu8lgyLpn8g:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=dbvrjAopSWA:Hu8lgyLpn8g:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=dbvrjAopSWA:Hu8lgyLpn8g:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jimmy-thinking/~4/dbvrjAopSWA" height="1" width="1" alt=""/>Mon, 26 Apr 2010 06:35:00 +0000http://feedproxy.google.com/~r/jimmy-thinking/~3/dbvrjAopSWA/mix10-part-21-server-side-web.html
http://jimmy.schementi.com/2010/04/mix10-part-21-server-side-web.htmlhttp://jimmy.schementi.com/2010/04/mix10-part-21-server-side-web.htmlMIX10, Part 1 – IronRuby, IronPython, and the web<div class="post-content">
<div style="border-bottom: #666 5px solid; border-left: #666 5px solid; padding-bottom: 5px; background-color: #333; margin: 0px 0px 10px; padding-left: 5px; padding-right: 5px; color: white; border-top: #666 5px solid; border-right: #666 5px solid; padding-top: 5px"> <p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" class="section"><em>This post is part of the “MIX10 – Pumping Iron on the web” series:</em></p> <ul style="padding-bottom: 0px; margin: 0px 0px 0px 20px; padding-left: 0px; padding-right: 0px; padding-top: 0px"> <li><strong>Part 1 - Introduction</strong> </li> <li><a href="http://blog.jimmy.schementi.com/2010/04/mix10-part-21-server-side-web.html">Part 2.1 – Server-side web development with dynamic languages</a> </li> <li><a href="http://blog.jimmy.schementi.com/2010/04/mix10-part-22-client-side-web.html">Part 2.2 – Client-side web development with dynamic languages</a> </li> <li><a href="http://blog.jimmy.schementi.com/2010/04/mix10-part-3-using-dynamic-languages-in.html">Part 3 - Using scripting in static applications</a> </li> <li><em>Coming soon: </em>Part 4 - Web-app extensibility with scripts </li> </ul> </div> <blockquote><em>The original post was mistakenly removed, so it’s been reposted with the original post date, 4/24/2010. Sorry if this confuses your blog readers or causes any other inconvenience.</em></blockquote> <p class="section">This past week I had the pleasure of attending and speaking at <a href="http://live.visitmix.com" target="_blank">MIX10</a> in Las Vegas about using <a href="http://ironruby.net" target="_blank">IronRuby</a> and <a href="http://ironpython.net" target="_blank">IronPython</a> on the web. If you’re a TV-person instead of a reading-person, here’s a video of the talk:</p> <p class="section"><a href="http://live.visitmix.com/MIX10/Sessions/FT09" target="_blank"><img style="display: inline" title="image" alt="image" src="http://lh3.ggpht.com/_OqCZhp9yI0Q/S6qrVHtweUI/AAAAAAAAAUg/RVL6vjAsKWM/image5.png?imgmax=800" width="400" height="225" /></a> </p> <p class="section">As I usually do, this series of posts will be a write-up of my talk … but first …</p> <blockquote class="section"> <p><strong><font color="#ff8000"><a href="http://lh3.ggpht.com/_OqCZhp9yI0Q/S6qrVURfhdI/AAAAAAAAAU8/anhVG5dFE8g/s1600-h/Slide10%5B1%5D.jpg" target="_blank"><img style="display: inline" title="Slide10" alt="Slide10" src="http://lh3.ggpht.com/_OqCZhp9yI0Q/S6qrWbaTf7I/AAAAAAAAAVE/Iv14jTJoBL0/Slide10_thumb.jpg?imgmax=800" width="360" height="270" /></a> </font></strong></p> <p><strong><font color="#ff8000">iron?</font> - </strong>Jim Hugunin and John Lam have both been quoted as saying &quot;Iron&quot; stands for different acronyms; &quot;Implementation running on .NET&quot; and &quot;It runs on .NET&quot;, respectively. I’m going to put my foot down and officially side with Jim, though really they are bacronyms; neither is actually the original meaning. A <a class="reference external" href="http://stackoverflow.com/questions/1194309/why-are-many-ports-of-languages-to-net-prefixed-with-iron">StackOverflow</a> post explains more, and I hope that puts the wondering to rest.</p> </blockquote> <p class="section">This talk is all about the why and how of <font color="#ff8000"><strong>embrace dynamic languages on Microsoft's web platform</strong></font> - be it on the web-server (IIS) or in the web-browser (Silverlight), and even in existing applications. To start out with, here’s my rational for why we as a developer community should care:</p> <p class="section">It’s no secret that <strong><font color="#ff8000">developers like things to be simple</font></strong>, and the web is pretty simple as far as application models go. While the web’s feature-set is pretty attractive itself (server-client oriented, instant client deployment, and cross-platform clients to name a few), the equally attractive development experience (simple UI mark-up system and a scripting language) still make it easy for people to build amazing websites.</p> <p class="section"><a href="http://lh4.ggpht.com/_OqCZhp9yI0Q/S6qrWn3XQ_I/AAAAAAAAAVM/quIxKntxHBk/s1600-h/Slide13%5B1%5D.jpg" target="_blank"><img style="display: inline" title="Slide13" alt="Slide13" src="http://lh3.ggpht.com/_OqCZhp9yI0Q/S6qrXpJmfOI/AAAAAAAAAVQ/IzeXCfL87tc/Slide13_thumb.jpg?imgmax=800" width="400" height="300" /></a> </p> <p class="section">Though the application model is simple, <font color="#ff8000"><strong>developers continue to evolve it</strong></font>; server and client frameworks are vital tools that make the web-development experience even more productive – it’s very rare that a website has no server side or client side dependencies.</p> <p class="section"><a href="http://lh4.ggpht.com/_OqCZhp9yI0Q/S6qrYKz9pvI/AAAAAAAAAVY/pzdJZgxmIAU/s1600-h/Slide18%5B1%5D.jpg" target="_blank"><img style="display: inline" title="Slide18" alt="Slide18" src="http://lh3.ggpht.com/_OqCZhp9yI0Q/S6qrYi1OSMI/AAAAAAAAAVg/gIK3pQR9eXI/Slide18_thumb.jpg?imgmax=800" width="400" height="300" /></a> </p> <p class="section">These frameworks provide such innovative features because they stand on the shoulders of powerful and expressive dynamic/scripting languages, giving the frameworks the unique ability to model the &quot;web&quot; as they see fit.</p> <p class="section">While each web-framework is powerful in its own right, the power really comes from the <font color="#ff8000"><strong>choice to use whatever tools help get things done</strong></font>. Developers and designers for .NET have the same need to get things done, and if <font color="#ff8000"><strong>getting things done is essentially the result of programming language choice</strong></font>, what choices are there? Really only C# and VB, which are static programming languages, requiring a compile step before execution and relying on debugging to see code in action. Take a look at the other languages mainly used on the web again -- they're all dynamic languages, running from source code, and providing interactive environments for running code. <strong><font color="#ff8000">Why is .NET static while the rest of the web is dynamic?</font></strong> Why can't they exist together? If .NET provided some language choice for developers, all the languages be used together, and the <font color="#ff8000"><strong>.NET community could benefit from the amazing work being done by dynamic language community</strong></font>, and visa versa.</p> <p class="section"><strong><font color="#ff8000">We in-fact live in this world</font></strong>, and embracing dynamic languages is possible on .NET, but <strong><font color="#ff8000">why would you want to do it</font></strong>? I'll discuss this in the following posts (links to posts coming soon):</p> <div class="section"> <ul> <li><a href="http://blog.jimmy.schementi.com/2010/04/mix10-part-21-server-side-web.html">Server-side web development with dynamic languages</a> </li> <li><a href="http://blog.jimmy.schementi.com/2010/04/mix10-part-22-client-side-web.html">Client-side web development with dynamic languages</a> </li> <li><a href="http://blog.jimmy.schementi.com/2010/04/mix10-part-3-using-dynamic-languages-in.html">Using dynamic languages in your existing web-applications</a></li> <li><em>Coming soon: </em>Opening up your applications to extensibility with scripts </li> </ul> </div>
</div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=QEthbGKxgnA:BlAfxbFDL54:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=QEthbGKxgnA:BlAfxbFDL54:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=QEthbGKxgnA:BlAfxbFDL54:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=QEthbGKxgnA:BlAfxbFDL54:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=QEthbGKxgnA:BlAfxbFDL54:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=QEthbGKxgnA:BlAfxbFDL54:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=QEthbGKxgnA:BlAfxbFDL54:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jimmy-thinking/~4/QEthbGKxgnA" height="1" width="1" alt=""/>Sat, 24 Apr 2010 07:10:00 +0000http://feedproxy.google.com/~r/jimmy-thinking/~3/QEthbGKxgnA/mix10-ironruby-and-ironpython-part-1.html
http://jimmy.schementi.com/2010/03/mix10-ironruby-and-ironpython-part-1.htmlhttp://jimmy.schementi.com/2010/03/mix10-ironruby-and-ironpython-part-1.htmlPyCon 2010: Python in the browser<div class="post-content">
<p><a href="http://us.pycon.org/"><img alt="PyCon 2010: Atlanta" src="http://www.processmechanics.com/media/pycon2010/speaking-pycon2010-400x60.png" /></a> </p> <p>Last weekend I was very fortunate to <a href="http://us.pycon.org/2010/conference/schedule/event/14/" target="_blank">speak</a> at <a href="http://us.pycon.org/2010/about/" target="_blank">PyCon 2010 in Atlanta</a> about <a href="http://ironpython.net/browser/" target="_blank">writing browser-based applications in Python</a>. A majority of the <a href="http://ironpython.codeplex.com/team/view" target="_blank">IronPython team</a> was also there; <a href="http://blogs.msdn.com/dinoviehland/" target="_blank">Dino Viehland</a> <a href="http://blip.tv/file/3263361/" target="_blank">spoke about IronPython Tooling in a keynote slot</a>, <a href="http://knowbody.livejournal.com/" target="_blank">Dave Fugate</a> gave a <a href="http://us.pycon.org/2010/conference/posters/accepted/#p6-behind-the-iron-curtain-testing-python-at-microsoft" target="_blank">poster presentation about testing IronPython</a>, and Bill Chiles was there for emotional support. It was also great to see <a href="http://www.voidspace.org.uk/" target="_blank">Michael Foord</a>, and also see how supportive the Python community is of IronPython.</p> <p>Here’s the write-up from my talk:</p> <h4><font color="#ff8000"><strong>Introductions and talk overview</strong></font></h4> <p>I primarily work on IronRuby, but when it comes to web technologies I give IronPython love as well. Actually, I was an intern back when it was just the IronPython team, and when I started full-time I was doing exactly what this talk is about -- getting Python running in the browser -- so I'm really excited to be talking about this at PyCon.</p> <p><font color="#ff8000">You, the Python developer, use Python because you want to, but in the browser you use JavaScript because you <i>think</i> you have to.</font> With IronPython you can write browser code in Python. I’ll only begin to answer &quot;<em>what can the browser bring to Python?</em>&quot; and &quot;<em>what can Python bring to the browser?</em>&quot; in this short overview; examples will be very simple (with the exception of a few flashy ones) to make sure you can get started immediately.</p> <p><strong><font color="#ff8000">Follow along</font></strong></p> <ul> <li><a href="http://blip.tv/file/3259502/" target="_blank">Watch the video of the talk from PyCon</a> </li> <li><a href="http://github.com/jschementi/pycon2010" target="_blank">Get all the demos from GitHub</a> (<a href="http://github.com/jschementi/pycon2010/raw/master/slides/jimmysch-python-in-the-browser.pdf" target="_blank">slides too</a>) (<a href="http://ironpython.net/browser/examples/pycon2010/" target="_blank">view online</a>)</li> </ul> <p>Also, all information and documentation about this can be found the <strong><em>new</em></strong>&#160;<a href="http://ironpython.net/browser/" target="_blank">ironpython.net/browser</a><strong></strong> page:</p> <p><a href="http://ironpython.net/browser/" target="_blank"><img style="display: inline" title="IronPython: Python in the Browser" alt="IronPython: Python in the Browser" src="http://lh6.ggpht.com/_OqCZhp9yI0Q/S5GF7qVWGTI/AAAAAAAAASw/sCtzGTVTac8/pythonbrowser%5B2%5D.png?imgmax=800" width="400" height="300" /></a> </p> <h5><font color="#ff8000"><strong>Setting Expectations</strong></font></h5> <p>“Python in the browser” is <strong><em><u>not</u></em></strong> Microsoft embracing and extending the browsers to support Python. In fact, this integration downloads python on demand, so there is no change required to the browser This is because <a href="http://silverlight.net" target="_blank">Silverlight</a> as the Python execution engine …</p> <p><a href="http://silverlight.net" target="_blank"><img style="display: inline" title="Slide6" alt="Slide6" src="http://lh6.ggpht.com/_OqCZhp9yI0Q/S5GF8DegJEI/AAAAAAAAAUY/nU2MGZZLF20/Slide6%5B1%5D.png?imgmax=800" width="400" height="300" /></a> </p> <p>… and if you’re wondering “What is Silverlight?” …</p> <blockquote> <p><a href="http://microsoft.com/silverlight">Silverlight</a> is a browser plug-in for Windows, and Mac OS (Novell makes a Linux version called “Moonlight”), which provide a managed execution engine for .NET-based programming languages in the browser, a rich set of vector-graphics-based UI features, and interop with the browser programming model and DOM. Go to <a href="http://silverlight.net">http://silverlight.net</a> for more information.</p> </blockquote> <h4><a name="Hello_World_11966306436806917_11799363233149052"></a><strong><font color="#ff8000">Hello, World</font></strong></h4> <p>Let's start with the latter, and show the most obvious thing Python can bring to the browser: <b><font color="#00c800">Python</font></b>.</p> <p>To develop a Python application in the browser, you just need your favorite text editor; so open it up, create a HTML file, reference <code>dlr.js</code>, and then you can use script-tags for running Python code:</p> <script src="http://gist.github.com/318169.js?file=helloworld.html"></script> <p>And the Python code does what you'd expect:</p> <p><a href="http://ironpython.net/browser/examples/pycon2010/start.html" target="_blank"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Hello from Python!" border="0" alt="Hello from Python!" src="http://lh4.ggpht.com/_OqCZhp9yI0Q/S5GPr44r_SI/AAAAAAAAATg/NgB7Pc0fCFY/hello-world%5B1%5D.png?imgmax=800" width="370" height="145" /></a> </p> <p style="border-left: orange 10px solid; padding-left: 10px">Though, I’d strongly suggest against writing any real app with your python <em>inline</em> with HTML, as it then can’t be reused. Sticking your python code in a .py file and referencing it from a script-tag is preferred for separation-purposes.</p> <p>Simple, right? Let's do something slightly more complicated, like handling mouse clicks. I'd prefer to do this in a REPL window, so let's turn one on in the browser; just place the following script-tag in the page:</p> <script src="http://gist.github.com/318169.js?file=repl.html"></script> <p><em>Note: you have <a href="http://github.com/jschementi/pycon2010/raw/master/repl.py" target="_blank">repl.py</a> locally if you downloaded the demos, or point to the <a href="http://github.com/jschementi/pycon2010/raw/master/repl.py" target="_blank">online one</a> directly.</em></p> <p>And now when you add <code>?console</code> to the page's URL a Python repl window will appear:</p> <p><a href="http://ironpython.net/browser/examples/pycon2010/start.html?console" target="_blank"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="IronPython REPL in browser" border="0" alt="IronPython REPL in browser" src="http://lh3.ggpht.com/_OqCZhp9yI0Q/S5GF9qHjXRI/AAAAAAAAATw/Jw05re18QuU/ipy-console%5B2%5D.png?imgmax=800" width="400" height="245" /></a> </p> <p>The console is hooked up to <code>sys.stdout</code>, so your existing text-based Python scripts can come alive in the browser (sans reading from stdin). Also, any print statements you use in the app will show up in the console as well, making it a great println-debugging tool.</p> <p>Let's play around with the page a bit, adding a DOM element and changing it's HTML content to &quot;Ouch!&quot; when clicked:</p> <script src="http://gist.github.com/318169.js?file=dom.py"></script> <h4><a name="How_all_this_works_51619907561"></a><font color="#ff8000"><strong>How all this works</strong></font></h4> <p>Wow, Python works in the browser! Let's look behind the curtain for a second to see what is really going on.</p> <p><a href="http://lh4.ggpht.com/_OqCZhp9yI0Q/S5GF9z6_85I/AAAAAAAAARI/1Xa_-MK8Odw/s1600-h/Slide9%5B3%5D.png"><img style="display: inline" title="Slide9" alt="Slide9" src="http://lh6.ggpht.com/_OqCZhp9yI0Q/S5GF-43d3LI/AAAAAAAAARM/H07zENyIddw/Slide9_thumb%5B1%5D.png?imgmax=800" width="400" height="300" /></a> </p> <p>dlr.js contains a collection of functions for creating a Silverlight control on the HTML page that is capable of running IronPython code.</p> <p><a href="http://lh5.ggpht.com/_OqCZhp9yI0Q/S5GF_WJ6OHI/AAAAAAAAARQ/Zs2OynTAJ18/s1600-h/Slide10%5B3%5D.png"><img style="display: inline" title="Slide10" alt="Slide10" src="http://lh6.ggpht.com/_OqCZhp9yI0Q/S5GF_vQmqnI/AAAAAAAAARU/F23H8Tffy10/Slide10_thumb%5B1%5D.png?imgmax=800" width="400" height="300" /></a> </p> <p>By default, just running dlr.js injects a Silverlight <code>&lt;object&gt;</code> tag into the page (immediately after the script-tag) so it can run only DOM-based scripts, and also scans for other script-tags indicating that you want a Silverlight rendering surface, but more on that later.</p> <p><a href="http://lh6.ggpht.com/_OqCZhp9yI0Q/S5GGADNQNjI/AAAAAAAAARY/3P9ucpP4vlQ/s1600-h/Slide11%5B3%5D.png"><img style="display: inline" title="Slide11" alt="Slide11" src="http://lh5.ggpht.com/_OqCZhp9yI0Q/S5GGATuqKBI/AAAAAAAAARc/nzeNu-SlsH0/Slide11_thumb%5B1%5D.png?imgmax=800" width="400" height="300" /></a> </p> <p>The injected Silverlight control points to a Silverlight application made specifically to embed the <a href="http://dlr.codeplex.com" target="_blank">dynamic language runtime</a>, the compiler/runtime/embedding infrastructure IronPython is built on, find all the Python code the HTML page uses, and executes it.</p> <p>The XAP is tiny, as the DLR and IronPython are in separate packages which are downloaded on-demand; the DLR and IronPython are not installed with Silverlight, so they must be downloaded with the application.</p> <p><a href="http://lh6.ggpht.com/_OqCZhp9yI0Q/S5GGAyQJvoI/AAAAAAAAARg/zZYmsKKs33c/s1600-h/Slide12%5B3%5D.png"><img style="display: inline" title="Slide12" alt="Slide12" src="http://lh5.ggpht.com/_OqCZhp9yI0Q/S5GGBUBagFI/AAAAAAAAARk/yZ0osMmBqSg/Slide12_thumb%5B1%5D.png?imgmax=800" width="400" height="300" /></a> </p> <p>However, if the application depends on the ironpython.net binaries, the user's browser will cache them and they won't be re-downloaded for any other app; almost as good as being part of the installer, while still being able to be open-source.</p> <p><a href="http://lh4.ggpht.com/_OqCZhp9yI0Q/S5GGBrQAl0I/AAAAAAAAARo/8ph1eYwqc1s/s1600-h/Slide13%5B3%5D.png"><img style="display: inline" title="Slide13" alt="Slide13" src="http://lh4.ggpht.com/_OqCZhp9yI0Q/S5GGBxTj5TI/AAAAAAAAARs/0D1ys0w-yn4/Slide13_thumb%5B1%5D.png?imgmax=800" width="400" height="300" /></a> </p> <p>Now user-code is able to run. Each inline Python script-tag is executed as if it was one Python module, and all other Python files execute as their own modules.</p> <div style="border-left: orange 10px solid; padding-left: 10px"> <p>To allow Python to be indented inside a script tag, the margin of the first line which does not only contain whitespace is removed. Line numbers in the HTML are preserved, so error messages show up correctly:</p> <p><img title="python error messages" alt="python error messages" src="http://docs.google.com/File?id=dcvr9mmg_161dvgrbnhm_b" width="380" height="157" /></p> </div> <p>The code is handed off to the DLR Hosting APIs (in the Microsoft.Scripting.Hosting namespace), which (a bit simplified) looks like this in C#:</p> <p><a href="http://lh5.ggpht.com/_OqCZhp9yI0Q/S5GGCd7esbI/AAAAAAAAARw/f6NhskEnmf4/s1600-h/Slide14%5B3%5D.png"><img style="display: inline" title="Slide14" alt="Slide14" src="http://lh3.ggpht.com/_OqCZhp9yI0Q/S5GGCzByChI/AAAAAAAAAR0/rU3Aj0WAbpE/Slide14_thumb%5B1%5D.png?imgmax=800" width="400" height="300" /></a> </p> <p>Executing Python code with the DLR hosting APIs is very straight-forward; essentially Python-eval for .NET-based languages. This hosting API abstract the “embedding” of Python away from the actual engine, so an application that hosts the DLR can use one API and switch between any language compatible with the DLR.</p> <p>For more information how how this all works, see the <a href="http://ironpython.net/browser/sl-back-to-just-text.pdf" target="_blank">paper</a> and the <a href="http://github.com/ironruby/ironruby/tree/master/Merlin/Main/Hosts/SilverLight/Microsoft.Scripting.SilverLight/" target="_blank">source code</a>. Also, for more information on the DLR, see the <a href="http://dlr.codeplex.com" target="_blank">DLR docs page</a>.</p> <h4><a name="Using_Python_libs_190130538307"></a><strong><font color="#ff8000">Batteries included here too</font></strong></h4> <p><em>Great, I can write python code in my browser, but how do I test it?</em></p> <p>A powerful part of Python is its standard-library; almost all Python applications depend on it, and it has some really useful libraries, like unittest. Here's a very simple test of the “say_ouch” app:</p> <script src="http://gist.github.com/318169.js?file=unittest.html"></script> <p><a href="http://ironpython.net/browser/examples/pycon2010/unittest.html?test" target="_blank"><img style="display: inline" title="image" alt="image" src="http://lh3.ggpht.com/_OqCZhp9yI0Q/S5GPsjED7zI/AAAAAAAAAT0/PFm7wnEnX5k/image%5B4%5D.png?imgmax=800" width="400" height="156" /></a> </p> <p>But where did unittest come from? Take a closer look at the first line:</p> <script src="http://gist.github.com/318169.js?file=py-stdlib.html"></script> <p>That zip file contains the pieces of the Python standard-library that unittest depends on.</p> <p style="border-left: orange 10px solid; padding-left: 10px">The Python standard library is a little less than 5MB compressed, so it's not <i>unthinkable</i> to include the whole thing for development, but for deployment you should just include the dependencies; unittest's dependencies are 58 KB.</p> <p>When a zip file's filename is added to the path, it is treated like any other directory; <code>import</code> looks inside it to find modules. You'll also notice that <code>import repl</code> just worked, even though <code>repl.py</code> isn't in the zip file; it was referenced by a script-tag earlier. It works because script-tags actually represent file-system entries; doing <code>open(&quot;repl.py&quot;)</code>, or <code>open(&quot;PythonStdLib/unittest.py&quot;)</code> would also work.</p> <p style="border-left: orange 10px solid; padding-left: 10px">For anyone familiar with the older XAP-file/Chiron-based way to build Silverlight apps with IronPython: this combined script-tag/zip-file file-system abstraction is what allows you to never need to put file in the main application's XAP.</p> <p>Another interesting library to in Silverlight is <a href="http://code.google.com/p/rst2xaml/" target="_blank">rst2xaml</a>, which takes any <a href="http://docutils.sourceforge.net/" target="_blank">reStructuredText</a>-formatted files and converts them to XAML to be rendered in Silverlight. </p> <p><a href="http://ironpython.net/browser/examples/pycon2010/rst2xaml/Silverlight/index.html" target="_blank"><img style="display: inline" title="rst2xaml" alt="rst2xaml" src="http://lh3.ggpht.com/_OqCZhp9yI0Q/S5GGDPfBzhI/AAAAAAAAAT4/cMpE12n1Jqg/rst2xaml%5B2%5D.png?imgmax=800" width="376" height="300" /></a> </p> <h4><strong><font color="#ff8000">Using .NET built-in and external APIs</font></strong></h4> <p>Now let's transition to what the browser can bring to Python; specifically the APIs that Silverlight exposes. Silverlight has a ton of functionality, and as I was only able to discuss a few Python libraries in Silverlight, I'll only be able to show a few Silverlight libraries being used from Python, but the entirety of Silverlight can be used from Python. See all the features Silverlight provides, as well as how to use .NET APIs in-general from Python.</p> <p>One interesting API is the <a href="http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.writeablebitmap(VS.95).aspx" target="_blank">WritableBitmap</a>, which gives you per-pixel access to render whatever you want. For example, here its used to render a fractal:</p> <p><a href="http://ironpython.net/browser/examples/pycon2010/mandelbrot.html" target="_blank"><img style="display: inline" title="mandelbrot" alt="mandelbrot" src="http://lh6.ggpht.com/_OqCZhp9yI0Q/S5GGD9uJvoI/AAAAAAAAAUE/yyq7DkCSv-k/mandelbrot1-400%5B1%5D.png?imgmax=800" width="400" height="301" /></a> </p> <p style="margin-top: 0px; padding-top: 0px"><em><font size="1">Example derived from </font></em><a href="http://www.silverlightplayground.org/post/2009/03/18/Silverlight3-WriteableBitmap.aspx" target="_blank"><em><font size="1">A.Boschin</font></em></a><em><font size="1">.</font></em></p> <p>This is even more interesting because the actual bitmap was generated by code written in C#, but called from Python:</p> <script src="http://gist.github.com/318169.js?file=mandelbrotbase.cs"></script><script src="http://gist.github.com/318169.js?file=mandelbrot.py"></script> <p style="border-left: orange 10px solid; padding-left: 10px">Source code summarized from both <a href="http://github.com/jschementi/pycon2010/blob/master/mandelbrot/mandelbrotbase.cs" target="_blank">mandelbrotbase.cs</a> and <a href="http://github.com/jschementi/pycon2010/blob/master/mandelbrot/mandelbrot.py" target="_blank">mandelbrot.py</a></p> <p>As with any computationally-intensive operations, it's a good idea to write them in a static pre-compiled language; for example the scientific-computation libraries for Python are actually written in C, but the library provide an API accessible to Python programmers. Unfortunately, CPython puts that responsibility on the library developer; not every C library can be directly consumed by Python code. However, this example shows that IronPython can call into any C# library, or any library written in a .NET language for that matter. This makes it trivial to just begin writing your application in Python, and then decide to convert the performance-sensitive sections to C#.</p> <p><a href="http://ironpython.net/browser/examples/pycon2010/webcam.html" target="_blank"><img style="display: inline" title="Hello from Python (and my webcam!)" alt="Hello from Python (and my webcam!)" src="http://lh3.ggpht.com/_OqCZhp9yI0Q/S5GGE-DmxZI/AAAAAAAAAUQ/mEIWALq39i0/webcam%5B2%5D.png?imgmax=800" width="400" height="468" /></a> </p> <p style="margin-top: 0px; padding-top: 0px"><font size="1"><em>Example derived from </em></font><a href="http://timheuer.com/blog/archive/2009/11/18/whats-new-in-silverlight-4-complete-guide-new-features.aspx#webcam" target="_blank"><font size="1"><em>Tim Heuer’s webcam-mic app</em></font></a></p> <p>Another interesting use of WritableBitmap is attaching different types of video sources to it, like a webcam! The upcoming version of Silverlight (version 4) supports webcam and microphone capture, and all that can be used from Python:</p> <script src="http://gist.github.com/318169.js?file=webcam.py"></script> <p style="border-left: orange 10px solid; padding-left: 10px">Webcam usage requires Silverlight 4 Beta; you can download the installer for <a href="http://silverlight.dlservice.microsoft.com/download/F/6/5/F653F7FD-AD4D-411D-8B1F-9C4B1BD69881/Silverlight_Developer.dmg">mac</a> or <a href="http://silverlight.dlservice.microsoft.com/download/F/6/5/F653F7FD-AD4D-411D-8B1F-9C4B1BD69881/Silverlight_Developer.exe">windows</a>.</p> <h4><a name="Tooling_356330999173224_48773967288434505"></a><strong><font color="#ff8000">Tooling</font></strong></h4> <p>The IronPython team’s big announcement at PyCon 2010 was the preview-availability of “IronPython Tools”, and add-on for Visual Studio 2010. This release was only distributed to PyCon 2010 attendees on CDs in their swag-bags, with a public release planned for the same time that VS 2010 final is released.</p> <p>IronPython tools comes with the beginnings of Silverlight support; for starters you can make a new Silverlight project:</p> <p><a href="http://lh5.ggpht.com/_OqCZhp9yI0Q/S5GGFAJXH9I/AAAAAAAAASM/CeP8aMSYXog/s1600-h/vs-newproj%5B4%5D.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="VS2010 New IronPython Silverlight project" border="0" alt="VS2010 New IronPython Silverlight project" src="http://lh5.ggpht.com/_OqCZhp9yI0Q/S5GGFtb5fOI/AAAAAAAAASQ/Gn3Nz0mp9UI/vs-newproj_thumb%5B2%5D.png?imgmax=800" width="400" height="217" /></a> </p> <p>IronPython tools uses the DLR hosting APIs for colorizing code:</p> <p><a href="http://lh3.ggpht.com/_OqCZhp9yI0Q/S5GGFzkqZbI/AAAAAAAAASY/ckkjDAfVu48/s1600-h/vs-colorization%5B4%5D.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="VS2010 IronPython colorization" border="0" alt="VS2010 IronPython colorization" src="http://lh6.ggpht.com/_OqCZhp9yI0Q/S5GGG8o92CI/AAAAAAAAASc/tBrpb04J7Cg/vs-colorization_thumb%5B2%5D.png?imgmax=800" width="400" height="277" /></a> </p> <p>And using Debug-&gt;Attach To Process you can set breakpoints in your python code (even code embedded in the HTML page) and use the Visual Studio debugger to step-through you app:</p> <p><a href="http://lh3.ggpht.com/_OqCZhp9yI0Q/S5GGHfiAeqI/AAAAAAAAASg/EmBGN8aDNGw/s1600-h/vs-debug%5B4%5D.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="VS2010 IronPython Silverlight debugging" border="0" alt="VS2010 IronPython Silverlight debugging" src="http://lh4.ggpht.com/_OqCZhp9yI0Q/S5GGHp7I7HI/AAAAAAAAASk/6zGdg6KOxZk/vs-debug_thumb%5B2%5D.png?imgmax=800" width="400" height="277" /></a></p> <h4><font color="#ff8000"><strong>Conclusion</strong></font></h4> <p>Now you know …</p> <ul> <li>What a Python browser app looks like </li> <li>What is going on behind the scenes </li> <li>How to use real python libs in the browser </li> <li>How to use Silverlight APIs from Python </li> <li>That there is a prototype of IronPython tooling! </li> </ul>
</div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=0NPREZRI59o:SeF-Dv1YdMM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=0NPREZRI59o:SeF-Dv1YdMM:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=0NPREZRI59o:SeF-Dv1YdMM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=0NPREZRI59o:SeF-Dv1YdMM:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=0NPREZRI59o:SeF-Dv1YdMM:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=0NPREZRI59o:SeF-Dv1YdMM:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=0NPREZRI59o:SeF-Dv1YdMM:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jimmy-thinking/~4/0NPREZRI59o" height="1" width="1" alt=""/>Fri, 05 Mar 2010 22:30:00 +0000http://feedproxy.google.com/~r/jimmy-thinking/~3/0NPREZRI59o/pycon-2010-python-in-browser.html
http://jimmy.schementi.com/2010/03/pycon-2010-python-in-browser.htmlhttp://jimmy.schementi.com/2010/03/pycon-2010-python-in-browser.htmlWhat can you get with 10KB of Ruby or Python code?<div class="post-content">
<h3><strong><font color="#ff8000">$1000 and a trip to MIX 2010!</font></strong></h3> <p><a href="http://mix10k.visitmix.com/" target="_blank"><img style="display: inline" title="mix10kart" alt="mix10kart" src="http://lh4.ggpht.com/_OqCZhp9yI0Q/S1eltjOaRdI/AAAAAAAAAQc/VYs1v6V0ECg/mix10kart%5B5%5D.png?imgmax=800" width="367" height="360" /></a>&#160;</p> <p><strong><font color="#ff8000">9 days left, an counting</font>, </strong>to <a href="http://mix10k.visitmix.com/Entry/Create" target="_blank">enter</a> your minimalist creation into the <a href="http://mix10k.visitmix.com/" target="_blank">MIX 10K Sm<strong><font color="#ff8000">art</font></strong> Coding Challenge</a>. Do anything you want, it just has to be less than 10 kilobytes of source code. You can use HTML5, or Silverlight, and also use <a href="http://visitmix.com/labs/gestalt" target="_blank">Ruby or Python through Gestalt</a> (<a href="http://mix10k.visitmix.com/Terms#4" target="_blank">learn more about the entry rules</a>). You can win a free trip to MIX and up to $1000 in cash (<a href="http://mix10k.visitmix.com/Terms#8" target="_blank">learn more about the prizes</a>).</p> <p>Check out the <a href="http://mix10k.visitmix.com/Gallery" target="_blank">already submitted apps</a> for inspiration; they are starting to look really awesome.</p> <p>As an added bonus, I’m part of the <a href="http://live.visitmix.com/News/MIX-10K-Judge-Panel-Announced" target="_blank">MIX 10K Judge Panel</a>! Since I work on <a href="http://ironruby.net" target="_blank">IronRuby</a> and <a href="http://ironpython.net" target="_blank">IronPython</a>, and wrote/maintain <a href="http://visitmix.com/labs/gestalt" target="_blank">Gestalt</a>, I’ll be <em><strong><font color="#ff8000">“very happy”</font></strong></em> if I you submit a Ruby or Python app. Of course I won’t be biased against JavaScript or C# based apps, but just sayin’ … ;)</p> <p>Entries will be accepted through January 29, so …</p> <style type="text/css">
#mix10k_enter,
#mix10k_enter:link,
#mix10k_enter:visited {
border-bottom: #666 3px solid; border-left: #666 3px solid; padding-bottom: 10px; background-color: #444; margin: 10px 50px 20px 0px; padding-left: 10px; padding-right: 10px; display: block; color: white; font-size: 24px; border-top: #666 3px solid; border-right: #666 3px solid; padding-top: 10px;
}
#mix10k_enter:hover {
background-color: #555;
text-decoration: none;
}</style><a id="mix10k_enter" href="http://mix10k.visitmix.com/Entry/Create" target="_blank"><strong>Enter your app right now »</strong></a>
</div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=-HZYKGdNefI:v9Z7I53DUZY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=-HZYKGdNefI:v9Z7I53DUZY:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=-HZYKGdNefI:v9Z7I53DUZY:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=-HZYKGdNefI:v9Z7I53DUZY:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=-HZYKGdNefI:v9Z7I53DUZY:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=-HZYKGdNefI:v9Z7I53DUZY:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=-HZYKGdNefI:v9Z7I53DUZY:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jimmy-thinking/~4/-HZYKGdNefI" height="1" width="1" alt=""/>Thu, 21 Jan 2010 00:54:00 +0000http://feedproxy.google.com/~r/jimmy-thinking/~3/-HZYKGdNefI/what-can-you-get-with-10kb-of-ruby-or.html
http://jimmy.schementi.com/2010/01/what-can-you-get-with-10kb-of-ruby-or.htmlhttp://jimmy.schementi.com/2010/01/what-can-you-get-with-10kb-of-ruby-or.htmlIronRuby @ RubyConf 2009 – Part 4: Project status<div class="post-content">
<em>This is part of a <a href="http://blog.jimmy.schementi.com/search/label/rubyconf">RubyConf 2009 series</a>:</em> <br /><a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-1-summary.html">Overview</a> | <a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-2-what-sets.html">What sets IronRuby apart?</a> | <a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-part-3-sneaking-ruby.html">Sneaking Ruby to the top</a> / <a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-35.html">Embedding IronRuby</a> | <strong>Project status</strong> <p>It’s been a long ride – starting in 2007 when IronRuby was introduced running in Silverlight. Things started out slowly, but for the last year we’ve moved pretty quick, have gotten great feedback, and IronRuby is due for another bump:</p> <p><a href="http://ironruby.net/download" target="_blank"><img style="display: inline" title="image" alt="image" src="http://lh5.ggpht.com/_OqCZhp9yI0Q/Sygeh-0Z_1I/AAAAAAAAAP4/GD1MmrErHsM/image8.png?imgmax=800" width="393" height="157" /></a> </p> <p>We’ve exceeded our goals for 1.0, and still plan on further <em>excess</em> before 1.0 is final. Let’s dive into our top goals: performance, compatibility, and CLR integration.</p> <p><a href="http://github.com/jschementi/rubyconf2009/raw/master/jimmysch-ironruby.pdf#page=21" target="_blank"><img style="display: inline" title="image" alt="image" src="http://lh6.ggpht.com/_OqCZhp9yI0Q/SygeiL81K1I/AAAAAAAAAP8/DwP64lYEJ_Y/image37.png?imgmax=800" width="400" height="315" /></a> </p> <p>We’ve been tracking performance against MRI 1.8.6, which though isn’t a final performance goal, it’s a good measure of performance for a 1.0. In the next major release we’ll start tracking MRI 1.9. In general we’re a significantly faster than MRI, but still a tad unacceptable compared to JRuby – that needs to be fixed before 1.0.</p> <p><a href="http://github.com/jschementi/rubyconf2009/raw/master/jimmysch-ironruby.pdf#page=22" target="_blank"><img style="display: inline" title="image" alt="image" src="http://lh3.ggpht.com/_OqCZhp9yI0Q/Sygeig7M38I/AAAAAAAAAQA/HL4H78JRRXE/image38.png?imgmax=800" width="400" height="277" /></a> </p> <p>We measure compatibility against RubySpec, as well as some popular Ruby libraries (only the top-used ones are shown here). We’re over 90% for every group of tests. In practice, compatibility is being tested against almost every library we can get our hands on, which is a ton, so I feel confident IronRuby 1.0 will be a very compatible Ruby implementation.</p> <p><a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-1-summary.html" target="_blank">As I said in a previous post</a>, this compatibility measure is against 1.8.6; IronRuby does not yet suppor 1.9 completely, though we may quickly change our opinion on this.</p> <p><a href="http://github.com/jschementi/rubyconf2009/raw/master/jimmysch-ironruby.pdf#page=23" target="_blank"><img style="display: inline" title="image" alt="image" src="http://lh4.ggpht.com/_OqCZhp9yI0Q/Sygei6fka6I/AAAAAAAAAQE/9429X2zalk4/image40.png?imgmax=800" width="400" height="221" /></a> </p> <p>CLR integration is very flushed out, supporting using all CLR classes, calling all methods, properties, etc, generics, inheritance, and all the other CLR features exposed to managed languages such as C# and F#. The only missing hole is generating actual CLR types and backings for Ruby types, though we feel this is an OK feature to ship without, because the work-arounds are simple. However, it will be a priority to fix in the next major release.</p> <p><a href="http://github.com/jschementi/rubyconf2009/raw/master/jimmysch-ironruby.pdf#page=24" target="_blank"><img style="display: inline" title="image" alt="image" src="http://lh5.ggpht.com/_OqCZhp9yI0Q/SygejVsjn_I/AAAAAAAAAQI/ekE2LnuRi2o/image41.png?imgmax=800" width="400" height="288" /></a> </p> <p>With RC1 being released, RC2, 3, etc. will come as the community reports issues that we all agree must be fixed by 1.0 final. As far as the core team’s priorities, we want to fix startup and throughput performance issues, as well as get through the backlog of bugs.</p> <p><a href="http://github.com/jschementi/rubyconf2009/raw/master/jimmysch-ironruby.pdf#page=25" target="_blank"><img style="display: inline" title="image" alt="image" src="http://lh4.ggpht.com/_OqCZhp9yI0Q/SygejmM9E1I/AAAAAAAAAQM/65NaDmK7Llo/image42.png?imgmax=800" width="400" height="227" /></a> </p> <p>After 1.0 is released, we’ll probably take a bit of a break, but then look to do some features we didn’t get to finish in 1.0, as well as Visual Studio Integration, since it’s the <a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=479957" target="_blank">highest voted feature for VS2010</a>:</p> <p><a href="http://lh4.ggpht.com/_OqCZhp9yI0Q/Sygej9QQQvI/AAAAAAAAAQQ/DKtfxg0iNXI/s1600-h/image36.png"><img style="display: inline" title="image" alt="image" src="http://lh5.ggpht.com/_OqCZhp9yI0Q/Sygek8N1qjI/AAAAAAAAAQU/SDpoVtBcprc/image_thumb17.png?imgmax=800" width="400" height="185" /></a> </p> <p>Download the <a href="http://ironruby.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=35312" target="_blank">IronRuby 1.0 RC1</a> and let us know what you think! You can <a href="http://ironruby.codeplex.com/WorkItem/Create.aspx" target="_blank">submit any issues you find to the CodePlex site</a>. <font color="#ff8000"><strong>Thanks!</strong></font></p>
</div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=SvnfkIFBkzY:WdpvN_rx8xs:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=SvnfkIFBkzY:WdpvN_rx8xs:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=SvnfkIFBkzY:WdpvN_rx8xs:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=SvnfkIFBkzY:WdpvN_rx8xs:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=SvnfkIFBkzY:WdpvN_rx8xs:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=SvnfkIFBkzY:WdpvN_rx8xs:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=SvnfkIFBkzY:WdpvN_rx8xs:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jimmy-thinking/~4/SvnfkIFBkzY" height="1" width="1" alt=""/>Tue, 15 Dec 2009 23:41:00 +0000http://feedproxy.google.com/~r/jimmy-thinking/~3/SvnfkIFBkzY/ironruby-rubyconf-2009-part-4-project.html
http://jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-4-project.htmlhttp://jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-4-project.htmlIronRuby @ RubyConf 2009 – Part 3.5: Embedding IronRuby<div class="post-content">
<p><em>This is part of a <a href="http://blog.jimmy.schementi.com/search/label/rubyconf">RubyConf 2009 series</a>:</em> <br /><a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-1-summary.html">Overview</a> | <a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-2-what-sets.html">What sets IronRuby apart?</a> | <a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-part-3-sneaking-ruby.html">Sneaking Ruby to the top</a> / <strong>Embedding IronRuby</strong> | <a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-4-project.html">Project status</a></p> <p>Imagine you’re building a program to help create animations, visualizations, and other interactive applications. The requirements are simple:</p> <ol> <li>2D rendering surface with simple primitive shapes </li> <li>Simple animation support – callbacks for each frame and each object on the canvas </li> <li>User-loadable “macros” for drawing and animating </li> </ol> <p>A .NET developer can easily code up the first two requirements in C#, but implementing the third will be tricky. What does a macro look like? How do I discover them? How can I make it interactive? Why is this so hard!? This scenario requires the user to input some data, and the program must make an animation out of it; the data of your program is the code. Here are the options most .NET developers would come up with:</p> <ul> <li>Domain specific language – people usually cop out here and make it XML-based, which happens to produce the most human-unreadable code ever. This DSL <em>could</em> also be GUI-based, but you won’t get any programmers interesting in extending your app that way. </li> <li>Completely punt on the interactivity and require the macros be .NET DLLs. </li> <li>Find a way to use C# interactively - either using <a href="http://msdn.microsoft.com/en-us/library/650ax5cx.aspx" target="_blank">CodeDom</a> to compile and run C# code dynamically (much like ASP.NET does), or code-generate a valid C# class from the snippet, compile it to a DLL (aka shell out to csc.exe), loading that DLL, and finally reflecting over that DLL to call the user’s code. This is, of course, ignoring the question of whether C# is a good macro language or not. <em>It’s worth noting that Mono supports </em><a href="http://www.go-mono.com/docs/index.aspx?link=N:Mono.CSharp" target="_blank"><em>hosting</em></a><em> it’s C# compiler, so you could do more dynamic things with C# through Mono.</em> </li> </ul> <p>Given all that talk about Ruby before, let’s try using IronRuby to write these macros. Here’s a C# app to start from:</p> <p><a href="http://lh5.ggpht.com/_OqCZhp9yI0Q/SycsxGvRmmI/AAAAAAAAAOo/rh-7Yk3_YoM/s1600-h/image%5B7%5D.png" target="_blank"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_OqCZhp9yI0Q/SycsxnTO4RI/AAAAAAAAAOs/SbrR43DWA3s/image_thumb%5B6%5D.png?imgmax=800" width="400" height="200" /></a> </p> <p align="center"><a href="http://github.com/jschementi/rubyconf2009/tree/sketchscript-part1" target="_blank">SketchScript starter on GitHub</a> (<a href="http://github.com/jschementi/rubyconf2009/zipball/sketchscript-part1" target="_blank">zip</a>)</p> <p align="center"><em>For the lazy, <a href="http://github.com/jschementi/rubyconf2009/tree/master/sketchscript" target="_blank">get the finished app’s source code</a> (<a href="http://github.com/jschementi/rubyconf2009/zipball/master" target="_blank">zip</a>), and a <font color="#ff0000">binary build (coming soon)</font>.</em></p> <p>The starter app does ABSOLUTELY NOTHING; just a Window with a <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.canvas(VS.100).aspx" target="_blank">Canvas</a> and a bunch of textboxes for coding. Keep in mind this is just a demonstration, and this app could have been written entirely in Ruby, but the point is to show .NET developers how powerful an embedded scripting language can be.</p> <h4><font color="#ff8000">Setting up your environment</font></h4> <p>.NET developers have choices for development environments: mainly <a href="http://www.microsoft.com/visualstudio" target="_blank">Visual Studio</a> or <a href="http://www.icsharpcode.net/OpenSource/SD/" target="_blank">SharpDevelop</a>, or even the command-line and text-editor (I left out <a href="http://monodevelop.com/" target="_blank">MonoDevelop</a> since Mono doesn’t support the Windows UI stuff I’m doing, but a future version will be able to run in Mono). I’ll be using <a href="http://download.microsoft.com/download/1/3/1/1316A924-AF88-4CC9-9661-CD1D2BBF3E5E/vs_proweb.exe" target="_blank">Visual Studio 2010 Beta 2</a> for this walkthrough’s screenshots and examples, specifically because it C# 4 has special dynamic language features,<strike> but you can also use C# 3 with Visual Studio 2008 (</strike><a href="http://www.microsoft.com/express/vcsharp/#webInstall" target="_blank"><strike>free version here</strike></a><strike>),</strike> or just stick to a text-editor and <a href="http://en.wikipedia.org/wiki/MSBuild" target="_blank">MSBuild</a>.</p> <p>If you’re using .NET 4.0, <code>sketchscript\sketchscript.sln</code> is the solution file you want to use. <strike>The .NET 3.5 version is <code>sketchscript\sketchscript3.5.sln</code>, but seriously, try out .NET 4.0</strike>.</p> <p><em><font color="#ff0000">I haven’t tested it out in VS2008 yet, so please bare with me. If you’re feeling adventurous, you can fork my git repo, get it working in VS2008, and I’ll pull your changes in.</font></em></p> <h4><font color="#ff8000">Adding references to IronRuby</font></h4> <p>If you downloaded SketchScript from the above link, you’ll find four DLLs required for embedding IronRuby in the <code>sketchscript\ironruby</code> directory. Add those as references to the sketchscript.csproj:</p> <p><a href="http://lh6.ggpht.com/_OqCZhp9yI0Q/Sycsx3szVGI/AAAAAAAAAOw/11s_xD274X8/s1600-h/image%5B8%5D.png" target="_blank"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_OqCZhp9yI0Q/SycsySkF0tI/AAAAAAAAAO0/G6YqFDt8y84/image_thumb%5B7%5D.png?imgmax=800" width="285" height="225" /></a> </p> <p>In case you’re curious about what each DLL is: <code>IronRuby.dll</code> is the IronRuby compiler, while <code>IronRuby.Libraries.dll</code> is the core libraries of Ruby. <code>Microsoft.Dynamic.dll</code> are the APIs that IronRuby depend on for DLR compiler features, and <code>Microsoft.Scripting.dll</code> is the DLR Hosting API.</p> <p><em>If anyone who has used IronRuby before is thinking there are missing DLLs, then you’re right. IronRuby’s <code>Microsoft.Scripting.Core.dll</code> has been integrated into .NET 4.0 as the new <code>System.Core.dll</code>. This also removes the need for <code>Microsoft.Scripting.ExtensionAttribute.dll</code>.</em></p> <h4><font color="#ff8000">Embedding IronRuby</font></h4> <p>Now let’s get that code window working; first add some <code>using</code> statements at the top of <a href="http://github.com/jschementi/rubyconf2009/blob/3db197e19f75832822e28811de90a76bd426cf40/sketchscript/sketchscript/MainWindow.xaml.cs#L19" target="_blank">MainWindow.xaml.cs</a>:</p> <script src="http://gist.github.com/255762.js?file=MainWindow-usings.xaml.cs"></script> <p>And some fields to hold onto the scripting engine anywhere in the <code>MainWindow</code> class:</p> <script src="http://gist.github.com/255762.js?file=MainWindow-fields.xaml.cs"></script> <p>Now initialize the scripting engine; add this code to the <code>Loaded</code> event action, after setting the <code>OutputBuffer</code> but before the <code>KeyBindings()</code> call (around line 71):</p> <script src="http://gist.github.com/255762.js?file=MainWindow-Loaded.xaml.cs"></script> <p>And lastly let’s run the code when Ctrl-Enter is pressed. Since that’s already set up for us, all we need to do is add this code in the <code>RunCode</code> method, right at the &quot;TODO&quot; comment around line 92:</p> <script src="http://gist.github.com/255762.js?file=MainWindow-RunCode.xaml.cs"></script> <p>And that’s it! Now you’ll be able to run some actual Ruby code:</p> <p><a href="http://lh5.ggpht.com/_OqCZhp9yI0Q/SycsyiiHxJI/AAAAAAAAAO8/6xVCyHphKOc/s1600-h/image%5B9%5D.png" target="_blank"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_OqCZhp9yI0Q/Sycsy8GOyTI/AAAAAAAAAPI/gEuDPxBZi9c/image_thumb%5B8%5D.png?imgmax=800" width="400" height="331" /></a></p> <h4><font color="#ff8000">Interacting with the host application</font></h4> <p>Though Ruby code can run, there is no obvious interaction with the host application. That black void of a canvas on the left would be completely useless if it wasn’t accessible from Ruby code, so add this single line to the <code>Loaded</code> event action, before the <code>KeyBinding()</code> call:</p> <script src="http://gist.github.com/255762.js?file=MainWindow-expose.xaml.cs"></script> <blockquote> <p><em>Note: if the host application didn’t do this, it would still be possible to get to the canvas from Ruby code, but the script writer would have to do it themselves:</em></p> <script src="http://gist.github.com/255885.js?file=without-host-help.rb"></script> <p><em>So, as a general rule-of-thumb, have your host program decide what parts to extend to script code, and have the script code only use that object-model, though their may be ways around it.</em></p> </blockquote> <h4><font color="#ff8000">Trying it out</font></h4> <p>Now that there’s a way to draw on the canvas, play around with drawing random things on the screen. Here’s a little script I’ve been playing with:</p> <script src="http://gist.github.com/255885.js?file=lots-o-squares.rb"></script> <p>Which draws this:</p> <p><a href="http://lh6.ggpht.com/_OqCZhp9yI0Q/SycszJJagnI/AAAAAAAAAPQ/1GpBiNQWFcc/s1600-h/squares%5B3%5D.jpg" target="_blank"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="squares" border="0" alt="squares" src="http://lh5.ggpht.com/_OqCZhp9yI0Q/SycszvE7NSI/AAAAAAAAAPY/teqQBnaIJkI/squares_thumb%5B2%5D.jpg?imgmax=800" width="400" height="445" /></a> </p> <p>Ooo, pretty! So without much effort we have a very extendable application. Before you get carried away playing around with making pretty things, there’s one more thing to do to make this app really awesome …</p> <h4><font color="#ff8000">Animation support</font></h4> <p>While animations could still be built with IronRuby’s native thread support or <a href="http://msdn.microsoft.com/en-us/library/ms752312.aspx" target="_blank">WPF animations</a> directly from Ruby code, it’d be nice for the host to provide some simple animation support, like a callback that fires for every frame, and even a way to attach animations to any object.</p> <p>The <a href="http://github.com/jschementi/rubyconf2009/blob/sketchscript-basicembed/sketchscript/sketchscript/MainWindow.xaml.cs#L158" target="_blank">host currently supports these two callbacks</a>, but they need to be wired up. Add the following code at the bottom of the <code>Loaded</code> event action, before the call to <code>KeyBindings()</code>: </p> <script src="http://gist.github.com/255762.js?file=MainWindow-RegisterCallback.xaml.cs"></script> <p>And also add this call at the end of the <code>RunCode</code> method:</p> <script src="http://gist.github.com/255762.js?file=MainWindow-CaptureCallbacks.xaml.cs"></script> <p>Lastly we need to implement <code>CatureAnimationCallbacks</code>, by looking for special method names to get a hold of. Look for <code>each_frame</code> as the <code>EachFrame</code> action, and <code>each_object</code> as the <code>EachObject</code> func.</p> <script src="http://gist.github.com/255762.js?file=MainWindow-CaptureCallbackImpl.xaml.cs"></script> <p>Now 30-times-a-second the host will try to call <code>each_frame</code>, and it will call <code>each_object</code> once for each element on the canvas, store the return value on the actual element, and then try to call an <code>update</code> method on that stored object 30-times-a-second. This lets you either run random animations, or specific behavior for objects.</p> <p>A good animation example is bouncing, so let's run the script that produced all the squares first, and then run the following code to make them all bounce.</p> <script src="http://gist.github.com/255885.js?file=bounce.rb"></script> <p>And now it should look something like this:</p> <object width="400" height="300"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=8185302&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=8185302&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="300"></embed></object> <p>There are more goodies to run in the <a href="http://github.com/jschementi/rubyconf2009/tree/master/sketchscript/features" target="_blank">features directory</a>, but try writing your own fun little animations. <a href="http://blog.jredville.com" target="_blank">Jim Deville</a> ported <a href="http://github.com/jcasimir/code_of_art/raw/master/documents/Code%20of%20Art%20-%20Tutorial.pdf" target="_blank">the tutorial</a> from <a href="http://github.com/jcasimir" target="_blank">Jeff Casimir’s</a> <a href="http://github.com/jcasimir/code_of_art" target="_blank">Code of Art</a> talk, which is pretty fun to play with, so if you make your own please post a comment with a screenshot and code!</p> <p><a href="http://github.com/jschementi/rubyconf2009/blob/master/sketchscript/features/circles.rb" target="_blank"><strong>circle.rb</strong></a></p> <p><a href="http://lh5.ggpht.com/_OqCZhp9yI0Q/Sycszz0ew-I/AAAAAAAAAPg/HPMRUr-U4OI/s1600-h/artclear2%5B2%5D.png" target="_blank"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="artclear2" border="0" alt="artclear2" src="http://lh3.ggpht.com/_OqCZhp9yI0Q/Sycs0eNOBVI/AAAAAAAAAPw/16GTRLcFXE4/artclear2_thumb%5B1%5D.png?imgmax=800" width="400" height="444" /></a>&#160;</p> <p>And there you have it, IronRuby embedded to do interesting things. In case you missed any steps along the way, <a href="http://gist.github.com/256632" target="_blank">here's the full diff</a> against the initial download.</p> <p><font color="#ff8000"><strong>Next stop, <a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-4-project.html">IronRuby’s status and roadmap</a>.</strong></font></p>
</div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=fPXOcw3JYmg:e_58eY65cP0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=fPXOcw3JYmg:e_58eY65cP0:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=fPXOcw3JYmg:e_58eY65cP0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=fPXOcw3JYmg:e_58eY65cP0:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=fPXOcw3JYmg:e_58eY65cP0:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=fPXOcw3JYmg:e_58eY65cP0:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=fPXOcw3JYmg:e_58eY65cP0:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jimmy-thinking/~4/fPXOcw3JYmg" height="1" width="1" alt=""/>Tue, 15 Dec 2009 06:29:00 +0000http://feedproxy.google.com/~r/jimmy-thinking/~3/fPXOcw3JYmg/ironruby-rubyconf-2009-part-35.html
http://jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-35.htmlhttp://jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-35.htmlIronRuby @ RubyConf - Part 3: Sneaking Ruby to the top<div class="post-content">
<p><em>This is part of a <a href="http://blog.jimmy.schementi.com/search/label/rubyconf">RubyConf 2009 series</a>:</em> <br /><a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-1-summary.html">Overview</a> | <a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-2-what-sets.html">What sets IronRuby apart?</a> | <strong>Sneaking Ruby to the top</strong> / <a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-35.html">Embedding IronRuby</a> | <a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-4-project.html">Project status</a></p> <p>Let’s be honest: not everyone uses Ruby. I know, it hurts to hear, but it’s the truth. To get a general idea of how <em>bad</em> it really is, let’s look at indeed.com’s job trends for Ruby, Python, Java, and .NET, and <em>assume </em>that’s a good measure of usage:</p> <div style="width: 540px"><a title="Ruby, Python, .NET, Java Job Trends" href="http://www.indeed.com/jobtrends?q=Ruby%2C+Python%2C+.NET%2C+Java"><img border="0" alt="Ruby, Python, .NET, Java Job Trends graph" src="http://www.indeed.com/trendgraph/jobgraph.png?q=Ruby%2C+Python%2C+.NET%2C+Java" width="400" height="222" /> </a></div> <p><strong>Holy crap!</strong> Regardless of the actual numbers, we all know what this graph is saying to be true. But why are dynamic language’s so <em>under-used</em>? Aside from the obvious, like fear of something different, the dynamic language community hasn’t sufficiently answered the “why” questions to the other camp, like “Why should I use Ruby if I already know .NET?”, and “why even bother.” Our answer has always been “Productivity, expressiveness, blah, blah, blah”; that turns out to be a horrible way to sell dynamic languages to people who love C# or Java for it’s productivity and expressiveness. =) However, their fears are justified; Ruby’s main usage today is for stand-alone apps (mainly websites, but there are some client apps), so they assume Ruby can’t be use it in their existing environment.</p> <h4><font color="#ff8000">Let’s solve this!</font></h4> <p>Let’s make it easy for those programmers at the top of the graph to use the languages at the bottom of the graph. Ruby gets to expand its ecosystem, and <em>enterprise</em> developers get a great dynamic language to use. Ruby is nicely position for this specific scenario since implementations of Ruby exist for both Java and .NET, so Ruby’s usage could become more on-par with Java and .NET. And here’s the way we make this happen: <font color="#ff8000">.NET and Java developers can easily <strong>embed</strong> Ruby into their existing applications for <strong>scripting</strong></font><em>.</em></p> <p><em>All this also applies for Python, and IronPython is forging this path along with IronRuby. This talk was for a Ruby crowd … I hope you understand <a href="http://www.voidspace.org.uk/" target="_blank">Michael</a> :). But don’t worry, <a href="http://blogs.msdn.com/dinoviehland/archive/2009/11/17/world-s-worst-paint-program.aspx" target="_blank">Dino Viehland</a> has already <a href="http://microsoftpdc.com/Sessions/FT30" target="_blank">begun brainwashing .NET developers for Python</a>.</em></p> <p><em>Also, since I work on IronRuby, I’ll be talking about this in relation to IronRuby and .NET from now on, though the same arguments work for JRuby and Java (and Jython). Check out the <a href="http://kenai.com/projects/jruby/pages/RedBridge" target="_blank">embedding JRuby page</a>, and <a href="http://www.jython.org/archive/21/docs/embedding.html" target="_blank">also how all this work in Jython</a>.</em></p> <p>The .NET people reading this might be smiling, but the Ruby people want to vomit … <em>(maybe partly because of .NET, but in all seriousness)</em> … because of the word “<em>scripting”</em>. I know, I too hate the negative associations “<em>scripting”</em> has; when I first started working at Microsoft I was openly against naming a component “Microsoft.Scripting”, but who listens to the new guy? For those who don’t get it, “<em>scripting”</em> makes these amazing languages sound like they are only useful for little toy things, and not for real work. Anyway, this plan takes advantage of that misconception, so don’t look at it as such a bad thing. :)</p> <h4><font color="#ff8000">Why and How?</font></h4> <p><em>Ok, .NET developers, stop reading … you’ll ruin the surprise! Just kidding. I love you. Read on …</em></p> <p>Since .NET developers see Ruby as a <em>scripting</em> language, it’s not a stretch to convince them that Ruby is good for embedding into their applications as a extensibility feature; allowing customize their application with bits of Ruby code. Here’s where all the <a href="http://en.wikipedia.org/wiki/Trojan_Horse" target="_blank">Trojans jump out of the wooden horse</a>. Getting Ruby into existing .NET applications is a much easier way for those developers to learn and use Ruby, rather than asking them to build a new app from scratch, or just look at tutorials, docs, etc, without having a good reason to. If .NET developers want to look at Ruby for use in their existing projects, then we’ve succeeded; it’ll then be pretty obvious that they can do <em>real </em>things with these <em>so-called</em> scripting languages. They’ll probably start using Ruby to prototype new features in their existing system, and then either keep that code as Ruby, or port some of it to their main language. Keep in mind, the goal isn’t to steal people from .NET – they would have left long ago like many of the Ruby community did – it’s to make Ruby co-exist with these more “enterprise” systems, and overall <font color="#ff8000"><strong>make software development fun again for everyone</strong></font>. </p> <p>But how do .NET developers really benefit from having a scripting language they can use from their current environments? Three words: <font color="#ff8000"><strong>No More XML</strong></font>. XML seemed to be the solution to all .NET developer’s problems since it was a way to make their environments more dynamic. It is easy to parse and walk XML, making it also easy to attach some meaning to seemingly meaningless angle-brackets. One could implement anything using this technique, even logic. Which is why XML became a dynamic language and meta-programming tool for .NET. But really <font color="#ff8000"><strong>XML is a work-around to these static languages lacking the ability to be treated as both code and data</strong></font>.</p> <p>Being able to use your code just like your data is liberating. For example, running Ruby code from just at string:</p> <script src="http://gist.github.com/254800.js?file=MainWindow1.cs"></script> <p><em>IronRuby supports the <a href="http://dlr.codeplex.com/Project/Download/FileDownload.aspx?DownloadId=91404" target="_blank">DLR Hosting API</a>, a language-neutral script hosting API for .NET. For instance, supporting another is just as easy as changing the 2nd line to &quot;IronPython&quot;.</em></p> <p>Imagine doing this with XML; you’d have to somehow encode what element and field you want to modify, along the value to update it to, and then use something like reflection to interpret the XML and do the work. And that’s just for this simple example of setting the text of a TextBlock. So using a real programming language allows for endless extensibility-possibilities. Ruby is especially interesting since it can be <font color="#ff8000"><strong>simple enough for non-programmers, but powerful enough for adding full features</strong></font>.</p> <p>Software which allows simple extensibility, like Firefox and Rails, tend to always create an ecosystem of extensions around them, which end up being one of the most compelling features of the program. Maybe that next app could be yours?</p> <p><strong><font color="#ff8000">Next up, <a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-35.html">an example of embedding IronRuby for graphics</a>.</font></strong></p>
</div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=FqDXGdwmjTQ:I3os6wsimV4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=FqDXGdwmjTQ:I3os6wsimV4:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=FqDXGdwmjTQ:I3os6wsimV4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=FqDXGdwmjTQ:I3os6wsimV4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=FqDXGdwmjTQ:I3os6wsimV4:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=FqDXGdwmjTQ:I3os6wsimV4:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=FqDXGdwmjTQ:I3os6wsimV4:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jimmy-thinking/~4/FqDXGdwmjTQ" height="1" width="1" alt=""/>Mon, 14 Dec 2009 09:28:00 +0000http://feedproxy.google.com/~r/jimmy-thinking/~3/FqDXGdwmjTQ/ironruby-rubyconf-part-3-sneaking-ruby.html
http://jimmy.schementi.com/2009/12/ironruby-rubyconf-part-3-sneaking-ruby.htmlhttp://jimmy.schementi.com/2009/12/ironruby-rubyconf-part-3-sneaking-ruby.htmlIronRuby @ RubyConf 2009 – Part 2: What sets IronRuby apart?<div class="post-content">
<p><em>This is part of a <a href="http://blog.jimmy.schementi.com/search/label/rubyconf">RubyConf 2009 series</a>:</em> <br /><a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-1-summary.html">Summary</a> | <strong>What sets IronRuby apart?</strong> | <a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-part-3-sneaking-ruby.html">Sneaking Ruby to the top</a> / <a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-35.html">Embedding IronRuby</a> | <a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-4-project.html">Project status</a></p> <p>First a little background for those new to IronRuby …</p> <p><a href="http://ironruby.net" target="_blank">IronRuby</a> is a Ruby 1.8.6-compatible implementation, with support for some 1.9 features like string encodings. IronRuby is built on-top of the <a href="http://msdn.microsoft.com/en-us/library/8bs2ecf4(VS.71).aspx" target="_blank">Common Language Runtime</a>, so certain runtime-specific Ruby features are not supported on IronRuby, like callcc, ObjectSpace, and native extensions. However, local-continuations are coming, and we are considering <a href="http://github.com/ffi/ffi" target="_blank">FFI</a> post-1.0 to support native code.</p> <p>IronRuby runs on the CLR (2.0 SP1+) and <a href="http://www.mono-project.com" target="_blank">Mono</a> (2.0+), so IronRuby runs on a ton of platforms, including Mac OS and Linux. IronRuby also runs in the browser with Silverlight and Moonlight, a 4MB runtime which allows you to use Ruby to build “rich internet applications” … basically anything doing vector-graphics, webcam, audio, etc in the browser.</p> <p>To at least prove IronRuby runs on the Mac, here’s IronRuby installing the activerecord gem:</p> <p><a href="http://lh5.ggpht.com/_OqCZhp9yI0Q/Sx9Py6Z2VkI/AAAAAAAAANw/UxvxdKdBEk0/s1600-h/image8.png" target="_blank"><img style="display: inline; margin-left: 0px; margin-right: 0px" title="image" alt="image" src="http://lh6.ggpht.com/_OqCZhp9yI0Q/Sx9P0XnNYUI/AAAAAAAAAN8/c3oXFsgZNwQ/image_thumb6.png?imgmax=800" width="400" height="110" /></a> </p> <p>Yay =P I spoke in-depth about this at <a href="http://en.oreilly.com/oscon2009" target="_blank">OSCON</a> this year, so if you’re interested in how IronRuby runs cross-platform, please read my <a href="http://blog.jimmy.schementi.com/2009/07/ironruby-at-oscon-2009-mono-moonlight.html" target="_blank">OSCON 2009 post</a>.</p> <p>While <font color="#ff8000">“IronRuby running everywhere”</font> is a great bullet-point, when would you use it instead of another implementation? I’ll briefly mention a few Windows-focused reasons, but the focus will be on things that work regardless of your platform.</p> <p>One of IronRuby’s goals is to be the premiere Ruby implementation for Windows. Any type of development possible on Windows should be great on IronRuby; GUI, console, DirectX, etc. And some of these benefits also go cross-platform; for example using .NET’s WinForms for GUI apps will let you run the same app on Window and Linux.</p> <p>Even systems management tasks can benefit from IronRuby – a scripting language that Windows developers can use for anything – like all the languages that come standard on Mac OS and Linux distributions.</p> <p>Web developers can also use IronRuby to deploy their Ruby-based apps on: IIS is a great web-server, and IronRuby will make it easy for Windows shops to justify using Ruby on Rails or any other Ruby-based web framework. An interesting factoid: <strong><font color="#ff8000">51% of traffic on wiki.rubyonrails.org is from Windows users</font></strong> (data source: <a href="http://merbist.com/" target="_blank">Matt Aimonetti</a> and the Rails Core Team) – I’m not quite sure what that means, but at a minimum it means people who have an interest in Rails are using Windows.</p> <h4><strong><font color="#ff8000">Ruby in the browser</font></strong></h4> <p>One of the great features of IronRuby is it’s ability to run in the browser. Unfortunately there isn’t a ton of information about how to do this, but a nice set of documentation is being prepared for when the new IronRuby site goes live. Here’s a sneak peak into how easy it is to run Ruby in the browser:</p> <script src="http://gist.github.com/252173.js?file=hello.html"></script> <p><strong><font color="#ff8000">The code in the “text/ruby” script-tag is actually running in the browser</font></strong> -- it's <b>not</b> sending the code to the server or anything like that. Ruby can be used to build HTML-only apps (<a href="http://blog.jimmy.schementi.com/2008/08/walk-through-silverlight-flickr-client.html" target="_blank">an Flickr photoviewer example walkthrough</a>), full vector-graphics-based apps (<a href="http://ironruby.com/tutorial" target="_blank">the IronRuby tutorial</a>), or a combination of both. These apps can also be run out of the browser; <a href="http://blog.jimmy.schementi.com/2009/06/ironruby-tutorial.html" target="_blank">this post shows the above tutorial running as a native Windows desktop app</a>. In the browser, this requires <a href="http://microsoft.com/silverlight" target="_blank">Silverlight</a> for Mac OS and Windows, or <a href="http://go-mono.com/moonlight-beta/" target="_blank">Moonlight</a> for Linux.</p> <p><strong><font color="#ff8000">Great, it’s easy, but what can I do with it?</font> </strong>Right now, the best source of documentation for this is my <a href="http://ironruby.com/browser/sl-back-to-just-text.pdf" target="_blank">Back to Just-Text with Silverlight</a> paper. A place-holder page for where all this info will be is <a href="http://ironruby.com/browser" target="_blank">http://ironruby.com/browser</a>, but like I said, there is much more to come. The <a href="http://www.visitmix.com/Labs/gestalt/" target="_blank">Gestalt project</a> has a ton of cool samples and information as well, but most of this will eventually live on the actual IronRuby website.</p> <p><em>For demos I showed during the talk, see <a href="http://github.com/jschementi/rubyconf2009/tree/master/gestalt" target="_blank">http://github.com/jschementi/rubyconf2009/tree/master/gestalt</a>.</em></p> <p><b><font color="#ff8000">Other than this being some cool technology, how could it actually be useful?</font></b> I <em>would not</em> recommend porting all your JavaScript to this, but this is useful anywhere you need to show graphs, charts, anything visually oriented, or really anything where the browser feature-set isn’t enough. Rather than writing in ActionScript for Flash, you could use Ruby and Silverlight. Once you have a good reason to require Silverlight for a page, then it opens up the possibilities for using Ruby in the browser for things you used to use JavaScript for. For example, imagine writing both your server and client code in Ruby, and even reusing code between the two.</p> <p><font color="#ff8000"><strong>It may not be the only way to run Ruby in the browser, but it’s the most web-friendly.</strong></font> It’s worth noting that JRuby lets you write <a href="http://github.com/hakunin/jruby-applet" target="_blank">Ruby inside a Java applet</a>, but that requires Java to be installed. While Java still has more market-penetration than Silverlight, Silverlight’s tiny size makes this an irrelevant point for me. Also, <a href="http://arstechnica.com/microsoft/news/2009/11/silverlight-4-beta-arrives-for-developers.ars" target="_blank">Silverlight is installed on 45% of the connected internet machines</a>, so Silverlight’s market share is briskly increasing.</p> <p>Also, <a href="http://hotruby.yukoba.jp/" target="_blank">HotRuby</a> lets you write Ruby which compiles down to JavaScript or Flash, and while the demos are very impressive, the implementation is <strong>very not </strong>completed, and hasn’t been updated for almost two years. HotRuby requires the Ruby source code to be compiled on the server with YARV, and then the serialized bytecode is run on the client with a JavaScript VM for Ruby (which is the incomplete part). It’s a promising project if someone picks it back up.</p> <p>Considering those alternatives, IronRuby’s script-tag development and just-html deployment make it the best experience for writing Ruby browser apps currently.</p> <p>Anyway, I’ll write more about this when I can point you at a real website that shows what all this can really do.</p> <p><font color="#ff8000"><strong>Next stop,<em> </em></strong><a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-part-3-sneaking-ruby.html" target="_blank"><strong><em>sneaking</em> Ruby to the top</strong></a><strong>.</strong></font></p>
</div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=BL2HTEFPbeo:itsYbskHeJ4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=BL2HTEFPbeo:itsYbskHeJ4:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=BL2HTEFPbeo:itsYbskHeJ4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=BL2HTEFPbeo:itsYbskHeJ4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=BL2HTEFPbeo:itsYbskHeJ4:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=BL2HTEFPbeo:itsYbskHeJ4:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=BL2HTEFPbeo:itsYbskHeJ4:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jimmy-thinking/~4/BL2HTEFPbeo" height="1" width="1" alt=""/>Wed, 09 Dec 2009 07:20:00 +0000http://feedproxy.google.com/~r/jimmy-thinking/~3/BL2HTEFPbeo/ironruby-rubyconf-2009-part-2-what-sets.html
http://jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-2-what-sets.htmlhttp://jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-2-what-sets.htmlIronRuby @ RubyConf 2009 – Part 1: Summary<div class="post-content">
<em>This is part of a RubyConf 2009 series:</em> <br /><strong>Summary</strong> | <a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-2-what-sets.html" target="_blank">What sets IronRuby apart?</a> | <a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-part-3-sneaking-ruby.html" target="_blank">Sneaking Ruby to the top</a> / <a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-35.html" target="_blank">Embedding IronRuby</a> | <a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-4-project.html" target="_blank">Project status</a> <p>Now that the turkey has settled and I’m back in Seattle, I’m finally getting around to writing about my time at <a href="http://rubyconf.org" target="_blank">RubyConf 2009</a> in <a href="http://www.bing.com/maps/#JmNwPTM3LjY3OTY2Njg3Njc5MjkxNX4tMTIyLjM4NTA2NDczNjAwODY0Jmx2bD0xMSZzdHk9ciZydHA9cG9zLjM3LjU4MDE3MzY4NjE0NjczNl8tMTIyLjM1MDQ2MDIxNjQwMzAxX0J1cmxpbmdhbWUlMkMlMjBDQV9fX2VffnBvcy4zNy43NzkxNjAwNjc0MzkwOF8tMTIyLjQyMDA0OTQ1ODc0MjE0X1NhbiUyMEZyYW5jaXNjbyUyQyUyMENBX19fZV8mcnRvcD0wfjB+MH4=" target="_blank">Burlingame, CA</a> (<strong><a href="http://www.bing.com/maps/#JmNwPTM3LjY3OTY2Njg3Njc5MjkxNX4tMTIyLjM4NTA2NDczNjAwODY0Jmx2bD0xMSZzdHk9ciZydHA9cG9zLjM3LjU4MDE3MzY4NjE0NjczNl8tMTIyLjM1MDQ2MDIxNjQwMzAxX0J1cmxpbmdhbWUlMkMlMjBDQV9fX2VffnBvcy4zNy43NzkxNjAwNjc0MzkwOF8tMTIyLjQyMDA0OTQ1ODc0MjE0X1NhbiUyMEZyYW5jaXNjbyUyQyUyMENBX19fZV8mcnRvcD0wfjB+MH4=" target="_blank">not San Francisco</a></strong>, <a href="http://rubyconf.org/" target="_blank">liars</a>! ;)). I spoke about IronRuby, got to meet a bunch of the other implementers, and overall had a great time. <a href="http://github.com/jredville" target="_blank">Jim Deville</a> also got to come along for free, since Microsoft was a Silver sponsoring of RubyConf – next year we should sponsor the internet-connections since everyone using Chad’s room’s wireless was, well, fun … but no promises ;)</p> <p><a href="http://www.flickr.com/photos/jdeville/4167967539/" target="_blank"><img style="display: inline" title="4167967539_e7d1e43df3_b" alt="4167967539_e7d1e43df3_b" src="http://lh3.ggpht.com/_OqCZhp9yI0Q/Sx9GJQci_sI/AAAAAAAAANk/xqb-WepnDQs/4167967539_e7d1e43df3_b%5B10%5D.jpg?imgmax=800" width="278" height="393" /></a> </p> <p>My talk was all about how IronRuby is extending the reach of Ruby. The two areas I focused on was “<a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-2-what-sets.html" target="_blank">running in the browser</a>” and “scripting existing applications.” And all that was sandwiched with a overview of the project and a status update. All content from the talk can be found in my <a href="http://github.com/jschementi/rubyconf2009" target="_blank">RubyConf 2009 GitHub repo</a>, but I’ll walk you through the talk with a couple of posts:</p> <ul> <li><a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-2-what-sets.html" target="_blank">What sets IronRuby apart? (brief highlight of Silverlight support)</a> </li> <li><a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-part-3-sneaking-ruby.html" target="_blank">Sneaking Ruby to the top</a> <ul> <li><a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-35.html" target="_blank">Embedding IronRuby</a> </li> </ul> </li> <li><a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-4-project.html" target="_blank">Project status</a> </li> </ul> <p><em><a href="http://github.com/jschementi/rubyconf2009/raw/master/jimmysch-ironruby.pdf" target="_blank">Here’s a direct-link to slides if you want them</a>.</em></p> <h4><strong><font color="#ff8000">Everyone else’s talks</font></strong></h4> <p>Here’s my strategy for attending talks: open laptop and code until the speaker catches my attention. When bored, go back to coding, and repeat. I got nothing done at RubyConf; irritating and refreshing at the same time. Maybe it was the shotty wireless, but I’ll stick with saying the talks were awesome. Here’s what I liked:</p> <p><strong><font color="#ff8000">Keynote - <strong>Yukihiro Matsumoto</strong></font></strong></p> <p>Matz outlined a new language called ZEPT: A general-purpose dynamic language which is great for distributed programming and metaprogramming. After explaining this very familiar language in some detail, he then turned it around and essentially said, “Wait, it’s Ruby! Kinda.” </p> <p>While Ruby’s syntax is great for metaprogramming and DSLs, it needs work for distributed programming to be really great, but this is being worked on. Ruby currently has most of the building blocks for distributed programming, like lambdas, enumerators, and continuations, and things like a lazy-array are planned for future versions of Ruby. He closed with, “You can create the future of programming by working on Ruby,” and that there are more advances in internal DSLs in Ruby’s future.</p> <p><a href="http://rubyconf.org/talks/83-code-of-art"><strong><font color="#ff8000">Code of Art</font></strong></a><strong><font color="#ff8000"> (Jeff Casimir)</font></strong></p> <p>Jeff handed out <a href="http://github.com/jcasimir/code_of_art/raw/master/documents/Code%20of%20Art%20-%20Tutorial.pdf" target="_blank">actual paper</a> for his talk, so he gets props for that. He <a href="http://github.com/jcasimir/code_of_art" target="_blank">demoed</a> <a href="http://github.com/jashkenas/ruby-processing" target="_blank">ruby-processing</a>, a port of the Java Processing library for making fancy graphics and visualizations; it uses JRuby. The main demo was a very simple “click-and-make-a-random-sized-circle” … so simple I had to rip it off for my talk. So, I sent Jim off with <a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-35.html" target="_blank">my demo</a> to <a href="http://github.com/jschementi/rubyconf2009/blob/master/sketchscript/features/circles.rb" target="_blank">hack it up</a>, and now we’re close to having a full 2D-only-port of ruby-processing for IronRuby. More about that later though.</p> <p><a href="http://rubyconf.org/talks/126-ffi-creating-cross-engine-gems"><strong><font color="#ff8000">FFI – creating cross engine gems</font></strong></a><strong><font color="#ff8000"> (Jeremy Hinegardner)</font></strong></p> <p><a href="http://github.com/ffi/ffi" target="_blank">FFI, Foreign Function Interface</a>, is a DSL for describing C-libraries in Ruby; very similar to writing a header file. A benefit of using writing an C-extension based on FFI is that it should be compatible with many ruby engines, as the compatibility burden is placed on the ruby engine rather than the extension implementer. Supporting FFI will be a reality for IronRuby after 1.0; I’ll put this on the project’s TODO list. Anyone interested in starting an FFI implementation for IronRuby?</p> <p><a href="http://rubyconf.org/talks/121-embracing-collaboration-with-j-ruby-and-java-script"><strong><font color="#ff8000">Embracing Collaboration with JRuby and JavaScript</font></strong></a><strong><font color="#ff8000">(Jon Crosby)</font></strong></p> <p>Jon’s talk got me smiling, since it’s the same problem I tried to solve with <a href="http://schementi.com/silverline" target="_blank">IronRuby on the client and server</a>, but decided a Rails-specific solution was just good for a demo. He started his talk out with “browser plugins are not an option” … crap =P. Jon walked through his design process, until landing on a solution that basically cuts Ruby out completely and uses JavaScript to build both the client and the server portions of a webapp, sharing implementations and data. Wow, that’s one way to do it. :)</p> <p><a href="http://rubyconf.org/talks/64-j-ruby-everywhere-"><strong><font color="#ff8000">JRuby Everywhere!</font></strong></a><strong><font color="#ff8000">(Charles Nutter &amp; Thomas Enebo)</font> </strong>– <a href="http://jruby.kenai.com/presentations/RubyConf%202009%20-%20JRuby.pdf" target="_blank">slides</a></p> <p><a href="http://rubyconf.org/talks/142-mac-ruby-ruby-for-your-mac"><strong><font color="#ff8000">MacRuby: Ruby for your Mac</font></strong></a><strong><font color="#ff8000"> (Laurent Sansonetti)</font></strong> – <font color="#ff0000"><strong>slides?</strong></font></p> <p><a href="http://rubyconf.org/talks/21-rubinius-in-one-act-or-rubinius-a-war-on-two-fronts"><strong><font color="#ff8000">Rubinius in One Act OR Rubinius: A War on Two Fronts</font></strong></a><strong><font color="#ff8000"> (Evan Phoenix)</font></strong> – <a href="http://www.slideshare.net/evanphx/rubyconf-2009" target="_blank">slides</a></p> <p><a href="http://rubyconf.org/talks/42-rippin-off-python"><strong><font color="#ff8000">Rippin’ off Python</font></strong></a><strong><font color="#ff8000"> (Chris Wanstrath)</font></strong></p> <p>I actually didn’t get to see this since it was at the same time as my talk. I saw someone say on Twitter that this was one of the best attended talk at RubyConf. Jerk :)</p> <p><a href="http://rubyconf.org/talks/65-ruby-mutants"><strong><font color="#ff8000">Ruby Mutants</font></strong></a><strong><font color="#ff8000"> (Charles Nutter)</font></strong> – <a href="http://jruby.kenai.com/presentations/RubyConf%202009%20Duby.pdf" target="_blank">slides</a></p> <p>Charlie talked about <a href="http://www.github.com/headius/duby" target="_blank">Duby</a> and Surinx, his Ruby-derivatives. Duby is a statically typed Ruby-like language, while Surinx is a dynamic-typed language which depends on <a href="http://jcp.org/en/jsr/detail?id=292" target="_blank">invokedynamic</a>. Duby’s nice in that it’s not very JVM-specific (other than the backend), so an upcoming project of mine will be to write a CLR backend for this – having a Ruby-like language that is basically a facade on the CLR will fill in a lot of the holes we have with IronRuby, and hopefully influence some future IronRuby work – just like JRuby is planning.</p> <h4><strong><font color="#ff8000">Other Thoughts</font></strong></h4> <p>No implementers care about Ruby 1.8.6 anymore; Ruby 1.9 is the focus for all future work. MacRuby isn’t even supporting 1.8.6. So why should IronRuby support it? Granted, JRuby supports 1.8.6, as well as other 1.9 features, but they have been a “real” implementation for a while. When IronRuby actually starts to get production apps, do we really think Rails 3.0 (which is Ruby 1.9 focused) won’t be standard by then? Personally I think IronRuby should re-evaluate it’s reasons for supporting Ruby 1.8.6; if we support 1.9, compatibility will get better as time goes on … where as supporting 1.8.6 is a sure-fire way to ensure a decrease level of compatibility in the future if we don’t keep up. Thoughts?</p> <p>Also I got to meet <a href="http://merbist.com/" target="_blank">Matt Aimonetti</a>, of the <a href="http://www.rubyrailways.com/rails-is-still-a-ghetto/" target="_blank">“Pr0n Star” fiasco</a>, but I’ll let that slide :) He’s seems genuinely excited about using Ruby in the browser with Silverlight, and also has always offered his help with promoting <a href="http://ironruby.net/Documentation/Rails" target="_blank">IronRuby on Rails</a>; he <a href="http://weblog.rubyonrails.org/2009/8/11/community-highlights-ironruby" target="_blank">interviewed me on the Rails blog</a> not too long ago. I look forward to seeing greater collaboration between the rest of the Ruby community on IronRuby, and hopefully this is the start.</p> <h4><strong><font color="#ff8000">Overall it was a blast, see you all next year!!</font></strong></h4> <p><a href="http://www.flickr.com/photos/jdeville/4168730340/" target="_blank"><img src="http://farm3.static.flickr.com/2553/4168730340_4e5f584c7f.jpg" width="400" height="266" /></a></p>
</div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=dudxMuYWxXo:nTJnx3ygphs:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=dudxMuYWxXo:nTJnx3ygphs:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=dudxMuYWxXo:nTJnx3ygphs:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=dudxMuYWxXo:nTJnx3ygphs:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=dudxMuYWxXo:nTJnx3ygphs:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?i=dudxMuYWxXo:nTJnx3ygphs:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jimmy-thinking?a=dudxMuYWxXo:nTJnx3ygphs:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/jimmy-thinking?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jimmy-thinking/~4/dudxMuYWxXo" height="1" width="1" alt=""/>Wed, 09 Dec 2009 06:39:00 +0000http://feedproxy.google.com/~r/jimmy-thinking/~3/dudxMuYWxXo/ironruby-rubyconf-2009-part-1-summary.html
http://jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-1-summary.htmlhttp://jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-1-summary.html