Using Notepad++ for Writing Ruby Programs in Windows

If you are writing small Ruby programs and you don’t need facilities such as debugging available in a full fledged IDE, I recommend using Notepad++ editor. Notepad++ has built in syntax highlighting for Ruby and is a light weight and fully featured code editor.

Download the latest version of Notepad++ from here. I recommend download the Windows installer version. The download size is about 5MB. Double click on the downloaded executable to install Notepad++.

Installing Notepad++ in Windows 7

Choose the folder where you want Notepad++ to be installed and click on Next.

Notepad++ installation options

Customize your installation and choose what you need. I recommend enabling plugins, themes and auto updater. Click on Next.

Notepad++ installation options

Click on "Don’t use %APPDATA%" option. When you select this option, all the customization you do in your Notepad++ installation will be stored in the installation folder itself. This way you can copy the installed folder to another machine if you need to change your machine.  Click on Install to complete Notepad++ installation.

Run Notepad++ editor by clicking on the desktop icon. Let us first configure Notepad++ for editing Ruby programs.

From the Notepad++ menu, click on Settings => Preferences. Click on Language Menu/Tab settings. Under the tab settings for [Default] modify the tab size and Replace by space options as shown below. We set the tab size to 2 and we set Replace by space option to use spaces instead of tab character.

Setting editor properties in Notepad++ for Ruby

Now we will add a custom menu in the Run menu for running Ruby programs. This way you can run Ruby programs directly from the Notepad++ editor. From the Notepad++ menu, click on Run => Run. This opens up the following window.

Configuring a shortcut for running Ruby programs in Notepad++

In the text field, enter the following command. In order for this to work, you need to have Ruby 1.9.x installed and the Ruby bin folder must be on the PATH environment variable. See this tutorial for step by step instructions on installing Ruby in Windows.

cmd /K ruby "$(FULL_CURRENT_PATH)"

Click on the Save… button to save this as a custom command.

Configuring a shortcut for running Ruby programs in Notepad++

Enter a name for the shortcut (Run Ruby Program) and then select a keyboard shortcut for running the command (F6). Click on OK.

Now from the Notepad++ menu, Click on Run. You will see the additional "Run Ruby Program" menu as shown below.

Custom Run Ruby option in Notepad++

In order for this shortcut to work, you need to ensure that your Ruby program is saved in a file. To test Notepad++, type in the following program,

Save the file as factorial.rb. Now press F6 key or select the "Run Ruby Program" submenu from the Run menu. You should see the output of the Ruby program in a command window as shown below,

Ruby program output from Notepad++

Installing Ruby on Windows 7 – Ruby 1.9.x Guide

Ruby LogoThis is a step by step guide on installing and using Ruby language on Windows 7 machines. A lot of applications now use the 1.8.x branch of Ruby. However it is being deprecated and if you are starting Ruby programming, you should start with the 1.9.x branch. This tutorial covers Ruby 1.9.3, the latest production release available as of writing this post.

Ruby 1.9.x introduces a number of key language improvements, faster execution and integrated library/package management using ruby gems. However the migration of tools and packages to Ruby 1.9.x is still on going and getting the language up and running with a decent IDE on Windows requires some effort. A large number of developers including the core Ruby developers use Linux or Mac systems for Ruby development and hence much of the documentation available focuses on installing Ruby on these platforms.

Installing Ruby on Windows 7

Ruby language is available as open source and ideally you should download the source code and compile it in your development platform to install Ruby. Luckily on Windows, Ruby is available as an installer. Download the latest Windows installer for Ruby from this page.  In this tutorial, I use Ruby 1.9.3-p0 and the download size is around 15MB. Click on the downloaded file to start Ruby installation.

Ruby Installation - License Terms

Accept license agreement and click on Next.

Ruby Installation - Options

Enable the "Install Tcl/Tk support" if you are planning to create GUI applications in Ruby. Also select "Add Ruby executables to your path". This enables you to invoke Ruby interpreter or programs from any command window. Click on Install to complete Ruby installation.

Exploring Windows Ruby Installation

Ruby - What is installed in WindowsExpand the Windows => Start => All Programs => Ruby 1.9.3-p0 to check whether Ruby is successfully installed. You will find the following items in the menu,

  • Interactive Ruby – This opens a command line Ruby interpreter session.
  • RubyGems Documentation Server – The starts an HTTP server by default listening on port 8808. The documentation for all the gems installed in your Ruby installation can be viewed by accessing this URL – http://localhost:8808/
  • Start Command prompt with Ruby – This opens a standard Windows command prompt with ruby’s programs available in the path environment variable. Type in the command ruby -v in the command line if you want to verify this.
  • Uninstall Ruby 1.9.3-p0 – Get rid of Ruby if you are bored with it
  • Documentation – Complete Ruby documentation including the documentation for core and standard library is available as a windows help file. Also included is a free PDF book titled "The Book of Ruby" written by Huw Collingbourne.

Selecting an IDE for Ruby Programming in Windows

Following are some of the IDEs commonly used in Windows for Ruby programming.

I prefer Aptana Studio 3 for writing Ruby programs in Windows. It has all the cool features you require when you write Ruby programs,

  • It is free!
  • Supports syntax highlighting
  • Integrated Ruby debugger!
  • Code assist and auto completion
  • Code outline (classes, modules and methods)

Installing Aptana Studio as Ruby IDE in Windows

Download the standalone Windows installer for Aptana Studio 3 from this link. If you already have Eclipse 3.5 or above installed, you can alternatively install just the Aptana plugin to enable Ruby support in Eclipse. However I prefer the standalone version. The download is about 140MB.

Double click on the downloaded installer.

Installing Aptana Studio 3

Select a destination folder for Aptana Studio and click on Next.  Choose defaults for the start menu options in the next screen and click on Next. Select file associations in the screen and click on Next and then click on Install to complete the installation. Installation may take a while since a large number of files are extracted.

Aptana Studio requires a Git version control system installation on your system for its scripting features. Thankfully it can also install a private copy of PortableGit for this purpose. When you start Aptana for the first time, you will be presented with the following screen.

Aptana Studio 3 - PortableGit Installation

Click on "Use PortableGit" button.

Aptana uses the concept of workspaces (from Eclipse) which by default is the location for all the projects you create. You can create the default workspace location from the menu, File => Workspaces => Other. If you select another workspace, you will need to configure PortableGit again. Also the workspace folder by default takes over 150MB of hard disk space including PortableGit!

To develop a Ruby program, Click on File => New => Ruby Project option from Aptana Studio. Let us create a simple Hello World program. We will create a project and then add our program to this project.

Creating a new Ruby Project in Aptana Studio 3

Enter the name of the project as "helloworld" and click on Finish. An empty project will be created in the workspace. From the App explorer or the Project explorer, right click and click on  New => File.

Creating a Ruby program in Aptana Studio 3

Type in the name of the file as helloworld.rb and click on Finish. Now you have an empty Ruby program in your project. Open helloworld.rb and type in the following program,

hello world output in Aptana Studio 3Save helloworld.rb and from Aptana menu, click on Run helloworld.rb. You will see the output of the program in the console window of Aptana. However if you try to debug the program from Aptana, you will get the following error,

Unable to find ‘rdebug-ide’ binary script. May need to install ‘ruby-debug-ide’ gem, or may need to add your gem executable directory to your PATH (check location via ‘gem environment’).

In order to debug Ruby programs Aptana requires the ruby-debug-ide gem. Ideally this should be a simple step, but as of writing this blog post, installing it requires a bit of effort.

Enabling Ruby Debugging Support in Aptana Studio 3

In order to debug Ruby programs in Aptana, the ruby-debug-ide gem is required. Installing the gem is a simple step. Run the following command from the command line (requires an active internet connection),

gem install ruby-debug-ide --platform=ruby

However this throws up the following error,

C:\jjc\tools\Ruby193>gem install ruby-debug-ide
Fetching: ruby-debug-ide-0.4.16.gem (100%)
ERROR:  Error installing ruby-debug-ide:
        The ‘ruby-debug-ide’ native gem requires installed build tools.

Please update your PATH to include build tools or download the DevKit
from ‘http://rubyinstaller.org/downloads’ and follow the instructions
at ‘http://github.com/oneclick/rubyinstaller/wiki/Development-Kit’

This means that I need to install Ruby development kit. This kit is required if you want to build native RubyGems from the source code.

Download the DevKit compressed file from the Rubyinstaller download page. I downloaded DevKit-tdm-32-4.5.2-20110712-1620-sfx.exe (20MB+ ). This is a 7zip self extracting archive. Run the program and choose a directory where you want DevKit to be installed. I  keep it as a subfolder under the Ruby folder.

Open a windows command prompt and change the directory to the DevKit folder.  Type the following command to configure DevKit installation.

ruby dk.rb init

This command will identify the Ruby installed by RubyInstaller as shown below.

Configuring DevKit for Windows

Now run the following command to enable DevKit for the Ruby installations in your machine.

ruby dk.rb install

For more details on the DevKit installation, check this page.

Now try installing the ruby-debug-ide gem from the command line. (Note: this step took a couple of minutes in my machine)

gem install ruby-debug-ide --platform=ruby

What I got is another set of errors (see below)! The problem is that the latest release version of ruby-debug-ide (4.16) cannot be built with Ruby 1.9.x.

Temporarily enhancing PATH to include DevKit…
Building native extensions.  This could take a while…
ERROR:  Error installing ruby-debug-ide:
        ERROR: Failed to build gem native extension.

        C:/jjc/tools/Ruby193/bin/ruby.exe mkrf_conf.rb
Building native extensions.  This could take a while…
Building native extensions.  This could take a while…

Gem files will remain installed in C:/jjc/tools/Ruby193/lib/ruby/gems/1.9.1/gems
/ruby-debug-ide-0.4.16 for inspection.
Results logged to C:/jjc/tools/Ruby193/lib/ruby/gems/1.9.1/gems/ruby-debug-ide-0
.4.16/ext/gem_make.out

installing ruby-debug-ide

This bug is already fixed in the latest source code of ruby-debug-ide. However it is not yet a release version. So we need to tell the gem tool to download and install the latest pre release version by passing the –pre command line switch.

gem install ruby-debug-ide --platform=ruby --pre

This installs latest pre release version of ruby-debug-ide (version 0.4.17.beta8 as of writing this blog post).

installing ruby-debug-ide

This will enable the debugging feature in Aptana Studio. Check the debugging feature by setting a break point on your program and then clicking on the debug icon. Now you are all set for developing Ruby programs in Windows!

Distributing your Ruby program as a standalone executable (exe)

Since ruby is an interpreted language, whenever you want to release your program you need to release the source code. Also your program users must install Ruby virtual machine before they can run your program. Is there a way to distribute ruby program as a standalone executable?

Erik Veenstra has created a nifty tool called RubyScript2Exe which can convert your ruby program to an executable program. It achieves this by combining ruby interpreter code and your source code files into a single exe file.

First download the RubyScript2Exe tool from here. It is a ruby program (950kb size). Create a simple ruby program called helloworld.rb and save it to the same location where RubyScript2Exe.rb is stored.

From the command prompt, type the following,

ruby rubyscript2exe helloworld.rb

You will see the following output on console. Now you have a standalone executable program (helloworld.exe) which can be executed in any Windows machine! Combined with Win32API, you can create cool command line apps for Windows.

creating windows exe using ruby

The only problem with this executable is that it contains the entire ruby VM and hence is large (helloworld.exe size is around 1.5MB). Also note that this is not really a ruby compiler. It doesn’t convert your ruby code to machine code. It only packages ruby virtual machine along with your ruby code. Hence the code is still interpreted.

RubyScript2Exe can also create executable files for Linux and Mac OS X (Darwin). RubyScrip2Exe is released under GNU GPL license.

Accessing Windows API from Ruby – Using Win32API library

Ruby is used extensively in Web applications thanks to Ruby on Rails. But you can also develop Windows applications using Ruby. Interestingly the Windows API support is part of the standard installation (only on Microsoft Windows installations) and it is quite easy to use it!

In order to use Windows API, you need to import “Win32API” library in your applications.
You can then use the Win32API class to create a reference to an API method and can call it. The following sample program shows how this can be done. This application will display a native Windows message box,

When you run the above program, you will get a message box similar to the following one,

Now let us analyze our sample program in depth. The first line imports the standard Win32API library. Then we create two variables (message and title) which will hold the message to be displayed and the title of the message box.

Now using Win32API.new, we are creating a new instance of a Windows API method. The first parameter (user32) indicates the DLL which contains the API method. In this case the DLL is user32.dll. The second parameter is the name of the API method (MessageBox). The third parameter is an array indicating the type of all the parameters passed to API method (MessageBox). In the array, L stands for long number and P stands for pointer to string (string variable). The last parameter indicates the return type. In this case I stands for Integer.

Now using call method on the API reference we invoke MessageBox method. Note that the type of parameters matches the third array parameter in the constructor. First parameter is the id of the parent windows (in this case there is no parent and hence 0) and the last parameter indicates the type of message box (0 indicates default message box).

Following is another sample ruby program which uses Windows API to print out the logged in user name and also the computer name,

In the above sample, note that the second parameter is a pointer to the size of the first parameter. In Ruby there are no pointers and hence the size needs to be passed as a string value. Also we need to use unpack method to remove the trailing null character returned by API call.

Check out the following API definition for GetUserName (from MSDN),

lpBuffer
A pointer to the buffer to receive the user’s logon name. If this buffer is not large enough to contain the entire user name, the function fails. A buffer size of (UNLEN + 1) characters will hold the maximum length user name including the terminating null character. UNLEN is defined in Lmcons.h.

lpnSize
On input, this variable specifies the size of the lpBuffer buffer, in TCHARs. On output, the variable receives the number of TCHARs copied to the buffer, including the terminating null character.

As you can guess, the parameter passing and parsing return values from API quickly becomes tedious. So from a productivity angle using Windows API to build full fledged Windows applications is not recommended.

Ruby-Talk – rb_str_new2 cleanup, ruby GUI libraries and Ruby vs Python

Note: This is a weekly round up of interesting stuff found on ruby-talk mailing list. You can subscribe to this list here.

1. Steven wondered whether it is necessary to clean up the string created from native C code(rb_str_new2) and passed to rb_funcall. Matz replied,

You don’t have to (and you shouldn’t) free string objects.

2. Mohsin asked which is the better Ruby GUI Library, Ruby-GTK or FXRuby?. Both seemed good candidates and there were some additional recommendations such as JRuby + Swing + Monkeybars(James). Daniel recommended WxRuby,

I’ve had very good results with WxRuby http://wxruby.rubyforge.org/; It didn’t take long to learn, is NOT very rubyish (basically the C++ APIs are reimplemented in Ruby), but was very useful for cross-platform development. So you might want to consider that as a third option.

3. There was a big discussion (started by Marc) on differences between Python and Ruby. Michael had some good points on Ruby,

a. Flexible syntax of Ruby

b. Enough support for functional programming without having to fight with the language

c. A friendly community – he laments that this is on the decline!

d. No syntactic whitespace as in Python

As Ruby and Rails is becoming a mainstream language/framework it is only natural that you get more of the RTFM type of questions in the mailing groups. In my opinion there is no point in bitching about it, but rather politely point to the relevant documentation.

As far as Rails is concerned it is a big mess. The Rails 2 is out, but there is no documentation for a beginner in Rails 2. All the books are still stuck at earlier versions and for any documentation available online you need to pay! The only book available (3rd edition of Agile Web development with Rails) is still in beta and requires a lot of rewrite before it can be useful. So it is only natural that you get basic rails questions even on Ruby mailing lists and forums!

In another thread Mohit gives this explanation,

I see this as a sign that Ruby is picking up and gaining traction in other places.  There was a time when there were a lot of people who were discovering Ruby on their own free will and were looking at documents (online or offline) and trying out different things.  As it gains traction, it approaches the point where people are having Ruby thrust on them (possibly more Rails than Ruby) either due to preference of people further up in the food chain or due to clients (specially in the case of outsourced projects).  In such cases, it’s likely that the engineer is just venting frustration about the language on a forum cos it’s something they werem’t born to, or achieved – it was thrust on them.

4. Tim wanted to know the best way to delete every other value in a ruby array.  For example [a b c d e f g h i j k] becomes [a c e g i k]. There were a number of solutions proposed,

Harry,

Yermej,

Joel,

10 unique ruby language features

Learning Ruby is easy if you already know a programming language. But there are some ruby language features which can cause headache for a programmer migrating from C++ or Java. In this post, I will look at 10 interesting language features that are unique to Ruby.

1. Objects everywhere! – In Ruby everything is an object including simple numeric values. Here is an example,

2. Blocks – Blocks is a powerful feature in Ruby which simplifies programming. Blocks are code blocks which can be passed as a parameter to a method. Using this feature it is easy to build code libraries which can delegate varying functionality to code blocks to be built later. Here is an example which prints out all elements in an array,

3. Implicit return value in methods – Value of the last expression in a method becomes the return value of the method. In Ruby return keyword is optional. In the following example, 8 is the return value,

4. In Ruby everything is open! – In Ruby you can easily extend classes and modules. This means that nothing in Ruby (including built in classes and modules) are closed!. Interestingly additional methods can be added to a class even at runtime. Here is an example in which we add a previous method to FixNum class (which is the data type for all integers),

5. Missing unary operators in Ruby – Unary operators ++ and — are not supported in Ruby. Instead you can use += operator.

6. Ruby supports parallel assignment – It is possible to change multiple variables in a single assignment. The best example is the swapping of two variables as given below,

7. In Ruby strings are mutable – In Ruby it is possible to change a string variable in place. Hence unlike Java, the same string literal when used multiple times will point to different object instances.

8. True and false in Ruby – In Ruby only nil and false evaluate to false. This means that everything else evaluates to true! Hence even the value 0 evaluate to true in ruby. Following code snippet will output “Hello World” on console,

9. Native support for ranges and regular expressions – Ruby language has native support for regular expressions and ranges.  This is backed up with a rich set of API methods. Control structures such as a case statement natively supports ranges for value comparison.

10. Method indicators – In Ruby the last character of a method name can indicate its behaviour. If the method ends with a question mark it indicates that the return value is boolean. If the method ends with an exclamation, it indicates that the method can change the state of the object. In many cases a non exclamation version of the method is provided which modifies a copy of the object.

What is a ruby symbol? – symbols explained

Many programmers who are new to Ruby get confused when they see Ruby symbols. A lot us came to know about Ruby language through Ruby on Rails projects. In Ruby on Rails, symbols are everywhere! So it is essential to understand the concept of symbols in Ruby.

A symbol in Ruby is an instance of the class Symbol. A symbol is defined by prefixing a colon with an identifier. :name, :id, :user etc. are examples of symbols.

Let us see what is there in the class Symbol.

Symbol class in Ruby contains one class method all_symbols and instance methods id2name, inspect, to_i, to_int, to_s and to_sym.

  • all_symbols – Returns an array of all the symbols in Ruby’s symbol table.
  • id2name – Returns the string representation of the symbol – :name.id2name returns “name”.
  • inspect – Returns the symbol literal
  • to_i – Returns an integer unique for each symbol
  • to_int – Same as to_i
  • to_s - Same as id2name
  • to_sym – Convert the symbol to a symbol!

Symbols are most commonly used in creating hashes. For example, consider the following hash,

We could have used strings instead of symbols in this case,

But the advantage in using symbols is the efficient use of memory. Maximum space taken by a symbol is never more than the space taken by an integer. This is because internally symbol is stored as an integer. In case of strings the memory space depends on the size of the string.

Also whenever a string is used in the program, a new instance is created. But for symbols, same identifier points to the same memory location! This can be easily checked by running the following,

The memory saved may look trivial in this case. But when a predefined hash key structure is used as parameter to a method and if the method is used many times in the program, the savings can be substantial! For example, in RoR a sample link is defined as,

The first parameter is the label used for the link and the second parameter is a hash. The second parameter is defined as a hash to enable dynamic parameters.

Now in the implementation of link_to method, a check is done to see if :action key exists in the hash and then corresponding value is used. Similarly :controller is also checked and if found is used. Hence using hashes is a good way to implement optional parameters.

In this example we could have used “controller” and “action” strings instead of symbols :controller and :action. But we will be missing two important advantages – efficient memory usage and speed of processing.

In a rails application, you might be using link_to hundreds of times. Assume that you have used it 10000 times in a big application. If we assume every call contained :controller and :action symbols, total memory required by the symbols = 2 * size of an integer. Whether we call link_to once or millions of times the memory taken remains same. But things would be different in case of strings as keys. Whenever a link_to is called 2 new strings “controller” and “action” will be created. Hence a total memory allocation of 10000*16 bytes would have done by Ruby interpreter (of course garbage collector will ensure memory usage at any point to be much less than this).

Second is the question of speed. We know that link_to internally compares hash key to :controller and :action. This is extremely fast since it is equivalent to comparing integers. But if we had used strings, comparison such as “controller”==”controller” is inefficient since it involves comparison of all the characters in it.

Strings are scoped and they get destroyed/garbage collected when the execution goes out of scope. But in case of symbols, they remain defined as long as the program is running. So if you have a very large number of symbols there could be a lot of unusable memory.

It is possible convert a string to symbol using the to_sym method. Hence “controller”.to_sym returns :controller. Symbol identifiers can be quoted and they can also contain special characters. Hence :”wow, this is a symbol!” is a valid symbol.

In short, symbols are used instead of strings wherever we care only about the identity and not the content. Why we use them? Because they are memory efficient and comparison operation on them are really fast.

Now if you are still confused about symbols, just forget about them. In time you will realize what they are! :-)

Using temporary files in Ruby – Tempfile.new

For certain programming solutions, you might need a temporary file. Different operating systems store temporary files in different locations. Also you don’t want to explicitly name the file since that is irrelevant in the program. How do you ensure that there are no filename conflicts? The solution for all these is to use library for temp file processing.

Ruby comes a with a default library ‘tempfile’ for handling temporary file creation. Given a filename prefix, it creates a temporary file in the following format.

[prefix]-[process].[unique_number]

This ensures that there is no conflict in creating multiple temporary files in the same directory. Once your program terminates the temporary file is automatically deleted. Also by default, the temporary file is created in the operating system’s temporary folder (In my ubuntu system it is /tmp).

In the following program, a temporary file with prefix ‘random’ to store 50 random numbers is created. When the program terminates you cannot see the temp file. Hence I have added a ‘gets’ which stops for user input. In my case I could see a temporary file named ‘random.5789.0′ under \tmp dir.

If you want to the temp file in a specific directory, you can pass the directory name as the second parameter to new. For example – Tempfile.new(‘new1′,’/usr/home/jay’)

A Quick Dose of Ruby History

When you are learning something new, the first thing you should check out is its history. When you go through the history, you get a better perspective. It is the same with Ruby language and hence let us get a quick dose of Ruby history.

Ruby programming language is created by a Japanese programmer, Yukihiro Matsumoto. He is popularly known as “Matz” in the Ruby community. Matz started work on the language sometime in February 1993. The first alpha version was released in December 1994. Since then there has been numberous releases and the current production release 1.8.6 was done on March 2007. On 25th December 2007 there was a development release of Ruby 1.9 (this is not intended for production systems).

Ruby 2.0 will be the next major release and it is intended to expand Ruby lanugage and to improve the interpreter performance.

Matz main goal in developing Ruby was to create a scripting language that was more powerful than perl, and more object oriented than Python. Matz named the language after the “Ruby” gemstone and is inspired by “Perl”. Major guiding philosophy for the language has been “the principle of least surprise”. The first thing many new programmers note in Ruby is its elegance.

Following are the key turning points in Ruby history,

  • 1993, Feb 24 – Matz starts work on Ruby
  • 1993, April – First “hello world” works in Ruby
  • 1995, December 21 – Ruby 0.95 was released to the public
  • 1996, December 25 – Ruby 1.0 was released
  • 1998, December – ruby-talk mailing list was started
  • 2000 – Official Ruby newsgroup started
  • 2001 – RubyConf started
  • 2001, December 15 – Pickaxe book on Ruby was released
  • 2003, August – Ruby 1.8.0 was released
  • 2004, July – Web application framework Ruby on Rails released
  • 2007, March – Ruby 1.8.6 was released
  • 2007, December 25 – Ruby 1.9 (experimental version) was released
  • ??? – Ruby 2.0 release in future

Using Ruby’s http library – download and process web pages – I

Ruby has excellent networking support. Ruby has low level networking features such as sockets and tcp/ip protocols. It also has a high level API for handling protocols such as http and ftp. In this post we will look the Ruby http library. We also look at how this library can be used to download and process web pages.

1. Downloading a web page using Ruby

Following code illustrates using net/http library for downloading the Google’s home page. You should see the google homepage html in console!

Now in my machine, this returns text which says “document has moved”. This is because google is send a redirect to www.google.co.in. Following code shows how we can handle http redirect.

Now how do we rewrite this if we need to use a proxy server to connect to internet? In Ruby it is pretty simple. Check out the new version below.