Scott Hanselman

Hanselminutes Podcast 197 - The Dynamic Language Runtime, IronRuby and IronPython with Jimmy Schementi

February 4, '10 Comments [1] Posted in DLR | Podcast | Python | Ruby
Sponsored By

image My one-hundred-and-ninety-seventh podcast is up. Scott sits down with Jimmy Schementi to find out what's the scoop with the DLR. Is it baked? What do I need to do to get started? What's the status of IronRuby - is it done? Will IronPython be a first class language or is it already? All these questions and more will be answered.

Subscribe: Subscribe to Hanselminutes Subscribe to my Podcast in iTunes

Download: MP3 Full Show

Links from the Show

Do also remember the complete archives are always up and they have PDF Transcripts, a little known feature that show up a few weeks after each show.

Telerik is our sponsor for this show.

Check out their UI Suite of controls for ASP.NET. It's very hardcore stuff. One of the things I appreciate aboutTelerik is their commitment tocompleteness. For example, they have a page about their Right-to-Left support while some vendors have zero support, or don't bother testing. They also are committed to XHTML compliance and publish their roadmap. It's nice when your controls vendor is very transparent.

As I've said before this show comes to you with the audio expertise and stewardship of Carl Franklin. The name comes from Travis Illig, but the goal of the show is simple. Avoid wasting the listener's time. (and make the commute less boring)

Enjoy. Who knows what'll happen in the next show?

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. I am a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web

The Weekly Source Code 29 - Ruby and Shoes and the First Ruby Virus

June 24, '08 Comments [11] Posted in Ruby | Source Code
Sponsored By

I was in Norway last week at the Norwegian Developers Conference, so I'm afraid the Weekly Source Code is the bi-weekly source code this month. It's amazing how international travel can really slow a body down. This trip just obliterated me. I'm slowly coming back to the world of the living, though.

I've been getting more and more interested in how folks extend their applications using plugins and things. In my new ongoing quest to read source code to be a better developer, Dear Reader, I present to you twenty-ninth in a infinite number of posts of "The Weekly Source Code."

This week's source is a clever "ClickOnce"-style hack for Ruby. It's cool because it brings together a number of technologies into a very clean end-user experience. The intent is to make the running of a Ruby GUI Application effortless, and it works and it's brilliant on several levels. Thanks to Sam Saffron for pointing me to it!

To start out, it's a hack says the author why the lucky stiff (or "_why" for short), so it's very early and there's bugs. You can check out the code on GitHub: http://github.com/why/shoes/tree/master or clone the whole tree using git via "git clone git://github.com/why/shoes.git"

Shoes

Ruby is a very aesthetically (to me) pleasing and flexible language. Shoes is a GUI Toolkit for making Windowing Applications using Ruby. I mentioned it back in TWSC12. Shoes is legendary for a number of reasons, but above all, it has the greatest API documentation in the history of all software documentation. The main book on Shoes Development called "nobody knows shoes" is fantastic. Even Chris Sells likes it!

Here's part of an example phone book application written in Ruby and Shoes):

Shoes.app :width => 320, :height => 350 do

stack :margin => 40 do
stack :margin => 10 do
para "Name"
@name = list_box :items => ["Yes, please!", "NO. No thankyou."]
end
stack :margin => 10 do
para "Address"
@address = edit_line
end
stack :margin => 10 do
para "Phone"
@phone = edit_line
end
stack :margin => 10 do
button "Save" do
Shoes.p [@name.text, @address.text, @phone.text]
end
end
end
end

It feels a lot like Tcl/Tk or Rebol. It'll be interesting to see if someone writes a mainstream application that is non-trivial. Shoes works on XP, Vista, MacOSX and Linux. Do note that you'll need to right click and run it as Administrator on Vista as _why hasn't put in an elevation prompt yet. You'll need Admin to do the initial bootstrap install.

However, in order to get Shoes to work, before today, you had to install Ruby, then get the Shoes libraries installed, usually via a gem. Then you'd need to run your app via ruby.exe yourapp.rb or a shortcut you'd setup.  The second comment on _why's blog post announcement says it all:

"Wow, this is super. We can actually give our apps to other people now :)"

Here's an explanation from _why on how the Shoes "bootstrapper" (my word) works:

If you poke around with a hex editor inside Windows’ PE binary format, you’ll find an .rsrc section at the end of the file which contains the icons and dialog boxes. I insert the Ruby script into this mess.
binj = Binject::EXE.new("blank.exe")
binj.inject("SHOES_FILENAME", "simple-accordion.rb")
File.open("simple-accordion.rb") do |f|
  binj.inject("SHOES_PAYLOAD", f)
end
binj.save("accordion.exe")

Fantastic hack. He shoves the Ruby script into a Windows Resource! He does the same thing for DMG (Disk Images) on Mac OSX, so you can create Ruby scripts that are portable to these two platforms.

When it runs, it checks for the existence of Shoes on your system. It's in C:\Program Files (x86)\Common Files\Shoes\. If Shoes (which includes a private copy of Ruby) is not there, it's downloaded and installed, and then your app runs. Bam, one-click cross-platform GUIs.

I'm not clear what the security ramifications are. Well, I am. I suspect there is no security that isn't already provided by the host operating system. Once you're running, the Ruby script has full control to do whatever it likes, so I suppose someone could write a malicious program just as they could write a malicious .NET app if they liked.

You can package your apps just by running shoes --package and you'll get this dialog. You can chose to include Shoes and Ruby inside the resulting EXE if you like.

 Shoes

Shoes also supports custom "Widgets." For example, here's a custom Speedometer control.

Shoes (2)

The code for the entire app, including the custom control is this:

class Speedometer < Widget
attr_accessor :range, :tick, :position
def initialize opts = {}
@range = opts[:range] || 200
@tick = opts[:tick] || 10
@position = opts[:position] || 0
@cx, @cy = self.left + 110, self.top + 100

nostroke
rect :top => self.top, :left => self.left,
:width => 220, :height => 200
nofill
stroke white
oval :left => @cx - 50, :top => @cy - 50, :radius => 100
(ticks + 1).times do |i|
radial_line 225 + ((270.0 / ticks) * i), 70..80
radial_line 225 + ((270.0 / ticks) * i), 45..49
end
strokewidth 2
oval :left => @cx - 70, :top => @cy - 70, :radius => 140
stroke lightgreen
oval :left => @cx - 5, :top => @cy - 5, :radius => 10
@needle = radial_line 225 + ((270.0 / @range) * @position), 0..90
end
def ticks; @range / @tick end
def radial_line deg, r
pos = ((deg / 360.0) * (2.0 * Math::PI)) - (Math::PI / 2.0)
line (Math.cos(pos) * r.begin) + @cx, (Math.sin(pos) * r.begin) + @cy,
(Math.cos(pos) * r.end) + @cx, (Math.sin(pos) * r.end) + @cy
end
def position= pos
@position = pos
@needle.remove
append do
@needle = radial_line 225 + ((270.0 / @range) * @position), 0..90
end
end
end

Shoes.app do
stack do
para "Enter a number between 0 and 100"
flow do
@p = edit_line
button "OK" do
@s.position = @p.text.to_i
end
end

@s = speedometer :range => 100, :ticks => 10
end
end

It's about 24 megs of libraries on disk when you're done, but you've got multimedia support and a lot of great library support in that space, not to mention a copy of Ruby itself. The download is only 2.5M bare or 6.8M with Video support.

I think it'd be great to build a Twitter Client using Shoes. The race is on! Hopefully we'll be able to get a Twitter Client done before some schmuck writes a Ruby Shoes virus. I for one, will be keeping the Ruby Shoes virus I wrote to myself. Well, not really a virus as it's a self propagating annoyance. But still. :)

It'll be fun to watch how this evolves. I hope there will be a clean upgrade process. If you want to try running your first Ruby/Shoes app, then run this EXE if you've got Windows or this DMG if you're on a Mac to see a basic demo application, but more importantly, to experience in the installer/bootstrapping process.

Technorati Tags: ,,

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. I am a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web

IronPython and the DLR march on

March 22, '08 Comments [12] Posted in ASP.NET | ASP.NET MVC | DLR | Python | Ruby | Silverlight
Sponsored By

I've got a number of emails complaining that folks haven't heard much from the DLR (Dynamic Language Runtime) and things like IronPython and IronRuby.

I think it's due to mostly one thing, the fact that the ASP.NET Futures Page still says July 2007. That's one of the reasons I personally fought to have the ASP.NET MVC not use a Date in its name. It just makes things look, ahem, dated.

I'm working to get that page updated, but I just wanted to make sure folks know that there's lots going on around the DLR. I talked to Mahesh on a video call just yesterday.

There's lots going on and here's some collected resources for you:

Once you've had fun with all that, you might look at John's Dynamic Silverlight in ASP.NET MVC article.

Here's John and Jimmy's talk on Dynamic Silverlight at Mix08:

All other goodness is at http://dynamicsilverlight.net/. Enjoy.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. I am a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web

The Weekly Source Code 20 - A Web Framework for Every Language

March 19, '08 Comments [15] Posted in Javascript | PHP | Programming | Ruby | Source Code
Sponsored By


vt102

We just keep oscillating back and forth between thin clients and chubby clients. We started with basic terminals receiving text from the server and displaying it, then added control codes and more smarts until we got into things like VT102 and beyond. We pushed all the User Interface over to the client for rendering.

Now that the Web is squarely here to stay, we've got islands of activeness in the form of browser plugins like Flash and Silverlight, some of which are cross platform and some less-so, but for now my quad-processor machine spends a lot of time either:

  • Waiting for markup to show up
  • Rendering markup

There's a thousand different ways to generate your UIs and send them down to the browser/client for rendering. Turns out there are as many ways as there are languages. If you've got a programming language, there's a web framework for it.

I don't know why this surprises me. Folks love their programming language, whatever it is, and it makes sense that the "ultimate" proof of their language's awesomeness would be the "ultimate web framework."

That said, it still seems funny to me that the greatest (er, most overtly visible) example of a language's superiority is how well it works as a Web Framework angle-bracket generator.

For example, Arc is Paul Graham's new LISP dialect that a number of people are talking about (with varying degrees of enthusiasm).  A tutorial on Arc is available here and there's an "Arc Challenge" being discussed here as folks try to this slightly more complex Hello World example:

"First generate a page with an input field and a submit button. If the user clicks on submit, he gets a second page with a link saying "click here." If he clicks on that, he gets a third page saying "you said: ..." where ... was whatever he put in the input field. This has to happen without the value being passed in the url; it should not be possible to change the behavior of the third page by editing the url in the second."

In Arc/LISP it looks like this:

  (defop said req
    (aform [w/link (pr "you said: " (arg _ "foo"))
             (pr "click here")]
      (input "foo")
      (submit)))

It's pretty terse to look at if you're used to doing things in more conventional languages. There's a lot of fun solutions like this entirely client-side one in JQuery:

$('body').append('<input id = "myInput" /><input type = "submit" />')
    .find('input[@type=submit]').click(function() {
       val = $('#myInput').val();
       $('body').html('<a href = '#'>click here</a>').find('a').click(function() {
          $('body').html('You said: ' + val);
       });
    });

Other examples include:

#!/usr/bin/env ruby
  require "ramaze"
  class MainController < Ramaze::Controller
    def index
      if f = session['foo'] then "you said #{f}"
      elsif session['foo'] = request['foo'] then A("click Here", :href => '/')
      else '<form><input name="foo" /><input type="submit"></form>'
      end
    end
  end
  Ramaze.start :port => 7001
  __END__ 

Then Rails:

def said
    if request.method == :post
      session[:said] = params[:said]
      render :action => "clickhere"
    else
      render :action => "result" if session[:said]
    end
  end

  default template said.rhtml:
  <% form_tag do %><%= text_field_tag "said", "" %><%= submit_tag %><% end %>

  clickhere.rhtml:
  <%= link_to "click here", "" %>
  
  result.rhtml:
  You said <%= session[:said] %>
| something |	
something := self request: 'Say something'.	
self inform: 'Click here'.	
self inform: something
serveAs "said" $ hasIndex $ \x -> "click me" `linksTo` (text ("You said " ++ x))
<%@ Page Language="C#" ClassName="WebApplication1._Default" %>
  <script runat="server">
    // C# and ASP.NET
    protected void SubmitButton_Click(object sender, EventArgs e)
    {
        MultiView1.ActiveViewIndex = 1;
    }
    protected void ClickHereButton_Click(object sender, EventArgs e)
    {
        SaidLabel.Text = string.Concat("You said: ", SayTextBox.Text);
        MultiView1.ActiveViewIndex = 2;
    }
  </script>

  <html>
  <head runat="server">
    <title></title>
  </head>
  <body>
    <form id="form1" runat="server">
      <asp:MultiView ID="MultiView1" runat="server" ActiveViewIndex="0">
        <asp:View runat="server">
          <asp:TextBox ID="SayTextBox" runat="server" />
          <asp:Button ID="SubmitButton" runat="server" Text="Submit" OnClick="SubmitButton_Click" />
        </asp:View>
        <asp:View runat="server">
          <asp:LinkButton ID="ClickHereButton" runat="server" Text="Click Here" OnClick="ClickHereButton_Click" />
        </asp:View>
        <asp:View runat="server">
          <asp:Label ID="SaidLabel" runat="server" />
        </asp:View>
      </asp:MultiView>
    </form>
  </body>
  </html>

Shorter but not-typical ASP.NET:

Shorter but non-idiomatic C#/ASP.NET:

    <%@ Page Language="C#" %>
    <html>
    <head>
    <title>Said</title>
    </head>
    <body>
        <form id="form" runat="server">
            <% if (!IsPostBack) { %>
                <input name="foo" />
                <input type="submit" />
            <% } else if (Request.Form["foo"] != null) {
                Session["foo"] = Request.Form["foo"]; %>
                <a href="javascript:form.submit()">click here</a>
            <% } else { %>
                you said: <%=Session["foo"]%>
            <% } %>
        </form>
     </body>
    </html>

There are so many ways to generate the same result. Big thanks to Ted Glaza for his indirect help on this post.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. I am a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web

2008 Window Scripting Games - Advanced PowerShell Event 7

March 4, '08 Comments [25] Posted in Learning .NET | PowerShell | Ruby
Sponsored By

Olympic_flameIn a few days the 2008 Scripting Games will come to an end. This is a yearly event that the Script Center does. There's a beginner and an advanced division and a bunch of deceptively hard problems. I was selected to be on of the "Guest Commentators (list here)" which really means they wanted me to solve one of the problems and provide the solution as an example. I'm not sure my solution is the best way, but it did solve the problem they assigned me.

My problem was Event 7: Play Ball! and I was to write a script that schedules all the games for a round-robin baseball tournament. The complete scenario is here, but in a nutshell:

"In a round-robin baseball tournament (or any kind of round-robin tournament, for that matter), every team plays each of the other teams in the tournament one time and one time only. For example, suppose we have a tournament with three teams (teams A, B, and C). In that case, the tournament would consist of the following set of games:

  • A vs. B
  • A vs. C
  • B vs. C

See how that works? Team A plays Team B and Team C; Team B plays Team A and Team C; and Team C plays Teams A and B."

A few other wrinkles thrown in are that the games must be randomized, otherwise Team A will play too many in a row and you need to schedule six teams, A through F. Of course, to be clear, every team must pay every other team once and only once. Here's my solution, hacked together quickly.

#this only works with an even number of teams
cls
[array]$global:games = $nul
function rotateArray($a)
{
 $first, $rest = $a
 $a = $rest + $first
 return $a
}
function makeGames($a)
{
 $i = 0;
 while($i -lt $a.Length/2)
 {
  $global:games = $global:games + ($a[$i].ToString() + " vs. " + $a[$a.Length-1-$i].ToString())
  $i++
 }  
}
$a = "A","B","C","D","E","F"
$z = 0
while($z -lt $a.Length-1)
{
 makeGames($a)
 # hold on to the first one
 
 $first, $rest = $a
 #rotate the rest
 $rest = rotateArray($rest)
 $a = [array]$first + $rest
 $z++
}
#randomize games
$a = [collections.arraylist]$global:games
$r = $a.count..1 |% {$R = new-object random}{$R.next(0,$a.count) |%{$a[$_];$a.removeat($_)}}
$r

Doing this in PowerShell took my brain a while to get. Note the RotateArray method's use of multi-variable assignment to chop up he array into first and rest. That wasn't obvious to me as a C-guy for the last 15 years, but it made my solution simpler when I refactored and introduced it.

The solution (remember, it's randomized) will look something like this:

B vs. D
B vs. C
A vs. D
B vs. F
C vs. D
A vs. F
A vs. B
C vs. F
E vs. F
A vs. E
D vs. F
B vs. E
D vs. E
A vs. C
C vs. E

Enjoy. Here's the same solution in Perl from Jan Dubois and again in VBScript. Who wants to do the F# version and the Ruby version? What about just LINQ to Objects?

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. I am a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web
Page 1 of 13 in the Ruby category Next Page

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.