A “FREE” Git and GitHub Course – 9th batch

Send to Kindle

A “FREE” Git and GitHub Course – 9th batch

Registrations are now open for RubyLearning’s popular “Pay if you like” online Git and GitHub course. This is an introductory but an intensive, online course for beginners. Here you’ll learn the essential features of both Git and GitHub that you’ll end up using every day.

What’s Git and GitHub?

Git is an open source version control system designed to handle very large projects with speed and efficiency, but just as well suited for small personal repositories (collection of resources that can be accessed to retrieve information); it is especially popular in the open source community. With GitHub you can host your public and private projects there and use it to collaborate on projects.

Ruby Master, Josh Susser1 in an interview with RubyLearning said:

First off, get an account on GitHub. (If you haven’t learned git yet, get going on that too – it’s the future for open source SCM.) Then do some exploring around the various projects and see where you think you can jump in and contribute something. Pick a project that is currently under development and has an active community. You’ll have enough going on that you don’t want to be championing a project just yet.

Get involved in the Ruby community. Join GitHub

What Will I Learn?

The course topics in brief are:

  • What’s Version Control
  • What’s Git
  • Downloading and Installing Git
  • Create your SSH Key
  • Introduce yourself to Git
  • Add some additional Git settings
  • What’s GitHub?
  • Set up your GitHub account
  • Follow a Friend
  • Watch projects
  • Creating a new repository
  • Deleting and renaming repositories
  • Fork a repository
  • Push changes to a repository
  • Clone a public project
  • Add collaborators to a project
  • Collaborate with other users
  • Send a pull request
  • Merge changes from a pull request
  • Use project wikis
  • Create and delete branches and tags
  • Create GitHub pages
  • Gist
  • Exercises

Who’s It For?

The Git and GitHub course is a starting point for people new to Git and GitHub, to learn it as quickly and easily as possible.

Dates

The course starts on 3rd Aug. 2013 and runs for a week.

The first eight batches were a run-away success. So hurry, registrations have started.

Is the course really free?

A lot of effort and time goes into building such a course and we would really love that you pay at least US$ 10 for the course. Since this is a “Pay if you Like” course, you are under no obligation to pay anything at all and hence the course would be free for you. For those who contribute US$ 10 or more, we shall email them a copy of the book (.pdf) “Using Git & GitHub eBook” – the course is based on this book.

How do I register?

  • First, create an account on the site and then pay the fees of US$ 10 by clicking on the PayPal button Paypal
  • After payment of the fees please send us your name to satish [at] rubylearning [dot] org so that we can send you the eBook, which normally takes place within 48 hours.
  • If you want to take the course for free, please just create an account and send us your name (as mentioned above).

Technorati Tags: ,


(Powered by LaunchBit)

Introducing Heroku Fork

An application is more than source code – it’s executables, generated assets, runtime environments, dependencies, configuration, running processes, backing services and more. What if you could fork your entire app, not just your code?

heroku fork lets you create unique, running instances of existing applications right from the command line. These instances are live and available on Heroku immediately so you can change, scale and share them however you want.

How It Works

You can fork apps you own and apps you’re collaborating on. You must have the Heroku Toolbelt installed to use this feature. Fork an existing application by running the following command:

$ heroku fork -a sourceapp targetapp

The command:

  1. Copies the source app's precompiled slug.
  2. Copies the source app's config vars, excluding add-on-specific environment variables.
  3. Re-provisions the source app's add-ons with the same plan. Note that if you are using paid add-ons, you will be charged for their usage in the new app.
  4. Copies the source app's Heroku Postgres data, if present.
  5. Scales the web process of the new app to one dyno, regardless of the number of web processes running on the source app. This ensures you don’t pay for scale you may not need.

For more on the specific behaviors and limitations of heroku fork, please see the Dev Center article.

Today’s Use Cases

Demonstrable Pull Requests

The common practice for evaluating pull requests is cumbersome at best: submitters provide a screenshot (or animated gif) to illustrate the proposed change, or a maintainer pulls down the remote branch and previews the change locally. Using heroku fork, pull requests can be accompanied by the URL of a live fork of the app that demonstrates a real, interactive version of the new feature.

Quick Setup of Multiple Environments

Keeping development, staging, production and other environments as similar as possible provides the foundation for a healthy workflow. Using heroku fork you can quickly spin up new, homogeneous application environments for other stages of development. You may even want additional environments outside of the standard development/staging/production workflow – heroku fork provides a simple way to spin up more ephemeral environments to play with, modify or dispose of as desired.

Migration to EU region

We recently launched Heroku Europe. heroku fork can be used to migrate your application to the Europe region:

$ heroku fork -a sourceapp targetapp --region eu

After verifying add-on provisioning and config vars in the new application, you can take steps to complete migration, such as migrating any production data not stored in Heroku Postgres and adjusting DNS settings.

Future of Fork

We want to empower teams to work faster and smarter: test new features, carry out experiments, and evolve rapidly. We think heroku fork provides the foundation for these things and more. We’d love to hear what you think of it and how you're using it. Email us.

Service Oriented Architecture talk – DevConTLV June 2013

It was an awesome day at the ”Ozen” bar in Tel-Aviv last week, met tons of cool people and watched more than a bunch on great talks by Shai Rubin on financial applications going wild and Alexander Fok’s erlang in the instant messaging world.

It was awesome, and any thanks need to go to [Raphael Fogel] for pulling this one yet another successful time.

My irregular talk was about what we as developers need to learn from the real world organizations about building a redundant, scalable and sustainable applications. And yes, by “real world scalable and sustain able organizations” I mean the drug cartel.

Here is the presentation, voice excluded of course.

don’t do drugs.

Service Oriented Architecture talk – DevConTLV June 2013

It was an awesome day at the ”Ozen” bar in Tel-Aviv last week, met tons of cool people and watched more than a bunch on great talks by Shai Rubin on financial applications going wild and Alexander Fok’s erlang in the instant messaging world.

It was awesome, and any thanks need to go to [Raphael Fogel] for pulling this one yet another successful time.

My irregular talk was about what we as developers need to learn from the real world organizations about building a redundant, scalable and sustainable applications. And yes, by “real world scalable and sustain able organizations” I mean the drug cartel.

Here is the presentation, voice excluded of course.

don’t do drugs.

Service Oriented Architecture talk – DevConTLV June 2013

It was an awesome day at the ”Ozen” bar in Tel-Aviv last week, met tons of cool people and watched more than a bunch on great talks by Shai Rubin on financial applications going wild and Alexander Fok’s erlang in the instant messaging world.

It was awesome, and any thanks need to go to [Raphael Fogel] for pulling this one yet another successful time.

My irregular talk was about what we as developers need to learn from the real world organizations about building a redundant, scalable and sustainable applications. And yes, by “real world scalable and sustain able organizations” I mean the drug cartel.

Here is the presentation, voice excluded of course.

don’t do drugs.

Developers’ Code Audio Book; Ruby 2.0 in print, lots of updates!

Developers’ Code Audio Book; Ruby 2.0 in print, lots of updates!

Redesigned Monthly Invoices

Earlier this month, we quietly rolled out a new design for our monthly invoices. It's a breath of fresh air compared to the previous iteration, and we thought it would be interesting to share what goes into a design like this.

At Heroku, billing is complex. Dyno hours are calculated to the second. Add-ons are calculated based on each provider’s pricing plan, which can be monthly or by usage depending on the add-on. There are support expenses, credits, free dyno hours, and packages. This all has to be wrangled into a format that not only makes sense for the backend systems that run calculations, but also for the human beings that use Heroku and need to understand what they’re paying for.

Our invoices have been falling short of the human-friendly requirement for a while. With the launch of 2X dynos, we realized our invoices needed to be updated to reflect the usage and pricing for multiple dyno sizes, and leapt at the opportunity to improve their overall quality.

Initial Designs

We began with the assumption that the most important thing for users isn’t an app-by-app breakdown of their charges, but instead a more general overview of the resources they’re paying for that can be summarized on a single page. Here’s our first mockup of that concept on an invoice:

First mockup

After a few iterations, we prototyped a basic version of our summary and new styles, and shared it with our Dashboard Beta users for a first round of feedback.

We gave our testers a URL that rendered their current invoice with the new design, and asked them to fill out a short survey on SurveyMonkey with a handful of open-ended questions.

User Feedback

We received feedback within minutes, and collected our most valuable and actionable data within the first 24 hours of user testing. We learned very quickly our users had a few other important requests:

  • Less verbose defaults

    For users with more than one or two apps, the previous invoice design could make it difficult to find the information you were looking for in a long wall of text.

  • Improvements to invoice emails

    The summary at the start of the invoice was very popular, but many users wanted to see that same information in the email we send at the beginning of the month to let users know that we’re about to bill their account.

The Final Product

Based on the feedback above and from other testers, we continued to iterate until we were happy with the design. Today, when you view your current usage details from Dashboard, you'll see our new design. Here’s a breakdown of some of the major changes we’ve made:

At-a-glance summary of major information

At-a-glance summary

Every invoice begins with a new section containing line items for your application dynos, add-on services, Heroku credits, one-off charges, and your invoice total.

Improved readability and visuals

Improved readability

The typography and layout of the entire invoice has been redesigned to highlight important information while removing distractions.

Collapsible application details

Expanded application detail

By default, the details for all apps on your invoice are collapsed into one line item. Expanding an app’s line item will break out your dyno and add-on usage with the same level of detail as the previous invoice design. This way, you can view your invoice with as much or as little detail as you’d like on an app-by-app basis (or click “Expand All” if you really liked viewing the details of all your apps at once).

Improved print & print-to-PDF styles

Printer dialog highlights new print styles

When printing your invoice, we remove unnecessary styles and elements. Your billing information and invoice summary are available by themselves on the first page, and apps are printed in the same expanded or collapsed state as when you were viewing your invoice in the browser.

Summaries in emails

Billing summary email

When your next invoice is ready, you’ll receive an HTML and/or plain text email with your billing information and invoice summary embedded in the message body so you can easily forward it to a manager or accountant.

Conclusion

We’re really excited to put the new design in your hands and browsers. We hope that with more readily accessible summaries and less overall clutter, we can remove some common pain points from the billing process. As always, we're constantly iterating on our designs, and we'd love to hear what you think. If you’d like to help us test new platform functionality, add-ons, and more in the future, join the Heroku Dashboard Beta program.

App Sleeping on Heroku

When talking to Heroku users, a question that frequently comes up is "when do my apps go to sleep, and why?". Though the behavior is documented in Dev Center, we'd like to provide more immediate visibility into the state of your apps at any given moment.

When Do Apps Sleep?

When an app on Heroku has only one web dyno and that dyno doesn't receive any traffic in 1 hour, the dyno goes to sleep.

When someone accesses the app, the dyno manager will automatically wake up the web dyno to run the web process type. This causes a short delay for this first request, but subsequent requests will perform normally.

Apps that have more than 1 web dyno running never go to sleep and worker dynos (or other process types) are never put to sleep.

Wakefulness in Dashboard

Starting today, we'll be exposing the wakefulness of your apps on your Dashboard app list.

All your apps now have an icon to indicate their current state. Here are the possible states your app can be in:

  • Awake and will never go to sleep
  • Awake, but will go to sleep after 1 hour of inactivity
  • Asleep
  • Not running because it has been scaled down or has no code

You can click on any of the icons to see more information, such as how long the app has been sleeping for, and a quick shortcut to wake it up again if it is asleep.

Learn More About India’s Exciting RubyConfIndia 2013

Send to Kindle

Learn More About India’s Exciting RubyConfIndia 2013

This guest post is by Prakash Murthy. Prakash is a Ruby programmer, working as a freelance web developer, splitting time between India and US, and currently based in Mysore. He discovered Ruby/Rails in early 2010 when he was looking to become a full-time programmer after more than a decade in a customer support role in the financial services software field, and has thrived in his chosen path ever since. He came to the Ruby world because of the effectiveness of Rails and staying here for the beauty of Ruby and the awesomeness of the community.

Prakash Murthy I am very excited to be heading to Pune, India tomorrow, to partake in the RubyConf India 2013 revelries.

Looking forward to meet with and learn from fellow Rubyists from around the world. Thrilled about getting to meet influential members in the global Ruby community including Jim Weirich, Aaron Patterson, Steve Klabnik and Andy Lindeman in my backyard so to speak.

The conference is being held on Saturday 22nd and Sunday 23rd July at Hyatt Regency Hotel in Pune. This is the fourth edition of RubyConf India.

I had attended the second edition of the conference in Bangalore back in 2011. That conference had left me impressed with a good mix of talks, and by being a very professionally organized event. Expecting this year’s event to better that experience by miles.

I have been actively involved in organizing this conference on and off for the last couple of months. Being aware of some of the milestones that were passed along the way makes me confidant that this year’s event will turn out to be very successful, and will leave the participants excited and thankful for being part of an awesome community around Ruby programming language in India.

5K run at RubyConfIndia 2013

My first involvement with the conference organization was with the 5K run at the event. The organizing team – headlined by Ajey Gore and Gautam Rege – thought it was a great idea to have a 5K run at this years conference, and gave me the go ahead to make it happen.

That led to the creation of ruby5k.in website to encourage many in the Indian Ruby community to take up running. So far, 84 people have signed up on ruby5k.in; and 23 people have posted training entries on the site. Happy about a few of the training entries being for the first ever time the person was running!

Anil Wadghule has been an awesome co-organizer for the ruby5k run, taking care of all the logistics locally, and getting Github to be a sponsor for the event, among many other things.

Thanks to Pragmatic Programmers for sponsoring 5 eBooks as prizes for the runners at ruby5k. The prize announcement did encourage a few more people to get serious about running!

Looking forward to a successful 5K run this Sunday morning, with many people enjoying a 5 km run with their fellow Rubyists, and having a great time at it, despite there being the possibility of rains.

Talks at RubyConfIndia 2013

Satish Talim, Hemant Kumar and I were on the panel to select the talks from among the 100+ talks that were submitted as a response to the Call for Proposals. We had a tough couple of days discussion to choose from among many very good proposals.

The selection process started by the three of us, on the panel, voting on the talks independently – the voting scale being 2 for Yes, 1 for Maybe/Backup and 0 for No.

Some numbers from this voting round: 8 talks got a 2 from each of us on the panel; 11 talks tallied a total of 5 points; 30 talks got a total of 4 points.

The list of talks were further refined after some discussion about the favorability of the topic + the speaker credentials + whether the topic has been dealt with elsewhere, etc. before the organizing team announced the final selected list of talks.

There were a couple of reversals as some of the selected foreign speakers couldn’t make the trip to India.

Nevertheless, the selection process has worked well and resulted in an excellent schedule at this year’s conference.

Something new in the schedule this time around is that two of the talks by Indian speakers will be on par with the keynotes – and will be in a full audience session (and not in a breakout session).

The two talks are:

  1. Turning blind eye to rails development “?”|” ! “!” by Siddhant Narendra Chote, and
  2. Taking Ruby Community in India to a New Level by me.

I am very excited to be one of the two Indians to address the full 500+ audience at this year’s RubyConf India! Hoping there will be more Indian keynotes at future conferences.

Opportunity Scholarship

One more part of the conference where I suggested an idea to the organizers and it was whole heartedly adopted!

I had seen Opportunity Scholarship in operation at last year’s Rocky Mountain Ruby Conference; thought it was a great way to increase diversity in the tech community.

The organizing team decided to take this program on for this year’s conference, and Satish Talim led the effort to co-ordinate with interested parties for awarding 14 scholarships. The scholarship included free entry to the conference as well as reimbursement of travel expenses up to a limit among other things. The objective of this program was to encourage participation by groups who were inadequately represented in the community.

More than 75 applications came in for the scholarship; Satish had the hard task of selecting 14 from among them.

The next part of the program was to pair each of the 14 selected for the Opportunity Scholarship with an experienced Ruby programmer who would act as their guide at the conference. 14 mentors were found in no time as the community’s response to a call for “Developer Sherpas” was amazing.

Read more about the Opportunity Scholarship along with the names of the scholarship winners and their developer sherpas at http://lanyrd.com/2013/rubyconfindia/calls/qqbk/

A note about sponsors at the conference

This is the first time at a RubyConf India that there is no Platinum Sponsor.

At each of the last three editions, ThoughtWorks was the Platinum Sponsor chipping in the biggest chunk of sponsorship money to cover the expenses of organizing the conference. This time around, there were more associate sponsors chipping in smaller amounts of sponsorship money, but enough to make it unnecessary to have a Platinum Sponsor.

I think this is a terrific development; it is a sign that the number of companies in the Indian Ruby ecosystem has increased significantly!

Thanks to all the companies who sponsored RubyConfIndia 2013.

What’s my expectation from the conference?

Did I mention I am very excited to be at the RubyConf India 2013 this weekend? The excitement comes mainly from being at the only Ruby conference in India. Am eager to meet with some old friends and make some new friends.

I am also excited and nervous at the same time about my talk. I am not very happy with the level of community activity around Ruby in India, and am hoping that my talk would encourage a discussion on the value of a strong local community around Ruby, and inspire a spree of Ruby-related events in many cities and towns around India.

On a related note, I am hoping to meet and discuss with a few people interested in doing something to better the Ruby community in their town; hoping to learn from these conversations, and to contribute in some small way to their efforts.

I am also eagerly looking forward to some of the talks, particularly the last keynote by Andy Lindeman as he has been teasing everyone about what will be in his talk all week.

So in summary, hoping to make more friends, learn some new stuff, make some impact, and have a lot of fun at this conference.

See you in Pune this Weekend!

If you are not attending RubyConfIndia 2013, do follow #rubyconfindia on twitter for some updates, and keep an eye out for Confreaks.com to put up the videos from the conference in a few weeks.

Feel free to ask questions and give feedback in the comments section of this post. Thanks!

Technorati Tags: , , ,


(Powered by LaunchBit)

Does the GIL Make Your Ruby Code Thread-Safe?

This is a guest post by Jesse Storimer. He teaches the Unix fu workshop, an online class for Ruby developers looking to do some awesome systems hacking in Ruby and boost their confidence when it comes to their server stack. Spots are limited, so check it out the class while there’s still room. He’s also the esteemed author of Working with Unix Processes, Working with TCP Sockets and Working with Ruby Threads.

There are some misconceptions in the Ruby community about this question surrounding MRI’s GIL. If you only take one thing away from this article today, let it be this: The GIL does not make your Ruby code thread-safe.

But you shouldn’t take my word for it.

This series started off just trying to understand what the GIL is at a technical level. Part 1 explained how race conditions could occur in the C code that’s used to implement MRI. Yet, the GIL seemed to eliminate that risk, at least for the Array#<< method we looked at.

Part 2 confirmed that the GIL did, in fact, make MRI’s native C method implementations atomic. In other words, these native implementations were free from race conditions. These guarantees only applied to MRI’s native C functions, not to the Ruby that your write. So we were left with a lingering question:

Does the GIL provide any guarantee that your Ruby code will be thread-safe?

I’ve already answered that question. Now I want to make sure that the misconception doesn’t go any further.

Race conditions redux

Race conditions exist when some piece of data is shared between multiple threads, and those threads attempt to act on that data at the same time. When this happens without some kind of synchronization, like locking, your program can start to do unexpected things and data can be lost.

Let’s step back and recap how such a race condition can occur. We’ll use the following Ruby code example for this section:

class Sheep
  def initialize
    @shorn = false
  end

  def shorn?
    @shorn
  end

  def shear!
    puts "shearing..."
    @shorn = true
  end
end

This class definition should be nothing new. A Sheep is not shorn when initialized. The shear! method performs the shearing and marks the sheep as shorn.

sheep = Sheep.new

5.times.map do
  Thread.new do
    unless sheep.shorn?
      sheep.shear!
    end
  end
end.each(&:join)

The bit of code creates a new sheep and spawns 5 threads. Each thread races to check if the sheep has been shorn? If not, it invokes the shear! method.

Here’s the result I see from running this on MRI 2.0 several times.

$ ruby check_then_set.rb
shearing...
$ ruby check_then_set.rb
shearing...
shearing...
$ ruby check_then_set.rb
shearing...
shearing...

Sometimes the same sheep is being shorn twice!

If you were under the impression that the GIL made your code ‘just work’ in the presence of multiple threads, this should dispel that. The GIL can make no such guarantee. Notice that the first time running the file, the expected result was produced. In subsequent runs, unexpected output was produced. If you continued running the example, you’ll see still different variations.

These unexpected results are due to a race condition in your Ruby code. It’s actually a common enough race condition that there’s a name to describe this pattern: a check-then-set race condition. In a check-then-set race condition, two or more threads check a value, then set some state based on that value. With nothing to provide atomicity, it’s possible that two threads race past the ‘check’ phase, then both perform the ‘set’ phase.

Recognizing race conditions

Before we look at how to fix this, first I want you to understand how to recognize this. I owe @brixen for introducing to me the terminology of interleavings in the context of concurrency. It’s really helpful.

Remember that a context switch can occur on any line of your code. When switching from one thread to another, imagine your program being chopped up into a set of discrete blocks. This sequential set of blocks is a set of interleavings.

At one end of the spectrum, it’s possible that there’s a context switch after every line of code! This set of interleavings would have each line of code interleaved. At the other end of the spectrum, it’s possible that there are no context switches during the body of the thread. This set of interleavings would have all the code in its original order for each thread. In between these two ends, there are lots of ways that your program can be chopped up and interleaved.

Some of these interleavings are OK. Not every line of code introduces a race condition. But imagining your programs as a set of possible interleavings can help you recognize when race conditions do occur. I’ll use a series of diagrams to show this code may be interleaved by two Ruby threads.

Just to make the diagrams simpler, I replaced the shear! method call with the code from the body of the method.

Consider this diagram the legend for the ones to follow; the code highlighted in red is the set of interleavings from Thread A, the code highlighted in blue is the set of interleavings from Thread B.

Now let’s see how this code could be interleaved by simulating context switches. The simplest case is if neither thread is interrupted during the course of executing this code. This would result in no race conditions and would produce the expected output for us. That might look like this:

Now I’ve organized the diagram so you can see the sequential ordering of events. Remember that the GIL locks around the execution of Ruby code, so two threads can’t truly run in parallel. The ordering of events here is sequential, starting at the top and working down.

In this interleaving, Thread A did all of its work, then the thread scheduler triggered a context switch to Thread B. Since Thread A had already done the shearing and updated the shorn variable, Thread B didn’t have anything to do.

But it isn’t always this simple. Remember that the thread scheduler could trigger a context switch at any point in this block of code. This time we just got lucky.

Let’s look at a more nefarious example, one that would produce unexpected output for us.

In this possible interleaving, the context switch occurs right at a point that can cause trouble. Thread A checks the condition and starts shearing. Then the thread scheduler schedules a context switch and Thread B takes over. Even though Thread A already performed the shearing, it didn’t get a chance to update the shorn attribute yet, so Thread B doesn’t know about it.

Thread B checks the condition for itself, finds it to be false, and shears the sheep again. Once it finishes, Thread A is scheduled again and finishes execution. Even though Thread B set shorn = true when it ran through the code, Thread A does it again because it picks up exactly where it left off.

A sheep getting shorn twice may not seem like much to care about, but replace sheep with invoice, and shearing with collecting payment; we would have some unhappy customers!

I’ll share one more example to illustrate the non-deterministic nature of things here.

This just adds more context switches, so each thread progresses a little bit at a time, but keeps switching back and forth. Let your mind take this to its logical conclusion, it’s possible for a context switch to happen on any line of the program. The interleaving that occurs can also be different each time the code is executed, so it may produce the expected result on one iteration, and an unexpected result the next time around.

This is really a great way to think about race conditions. When you’re writing multi-threaded code, you want to be thinking about how the program might be chopped up and interleaved, and the effects of various interleavings. If it seems that some interleavings will lead to incorrect results, you should re-think your approach to the problem or introduce synchronization with Mutex.

This is terrible!

At this point it seems fitting to tell you that you can make this code example thread-safe by introducing synchronization with Mutex. It’s true, you can do that. But I intentionally cooked up this example to prove a point;  it’s terrible code. You shouldn’t write code like this in a multi-threaded environment.

Whenever you have multiple threads sharing a reference to an object, and making modifications to it, you’re going to run into trouble unless you have some kind of locking in place to prevent a context switch from happening in the middle of the modification.

However, this particular race condition is easily solvable without explicitly using locks in your code. Here’s one solution using Queue:

require 'thread'

class Sheep
  # ...
end

sheep = Sheep.new
sheep_queue = Queue.new
sheep_queue << sheep

5.times.map do
  Thread.new do
    begin
      sheep = sheep_queue.pop(true)

      sheep.shear!
    rescue ThreadError
      # raised by Queue#pop in the threads
      # that don't pop the sheep
    end
  end
end.each(&:join)

I left out the Sheep implementation because it’s the same. Now, instead of each thread sharing the sheep object and racing to shear it, the Queue provides the synchronization.

If you run this against MRI, or any of the other truly parallel Ruby implementations, it will produce the expected result every time. We’ve eliminated the race condition in this code. Even though all the threads may call the Queue#pop method at more-or-less the same time, it uses a Mutex internally to ensure that only one thread can receive the sheep.

Once this single thread receives the sheep, the race condition disappears. With just one thread, there’s no one else to race with!

The reason I suggest using Queue instead of a lock is that its simpler to use a Queue correctly. Locks are notoriously easy to get wrong. They bring new concerns like deadlocking and performance degradations when used incorrectly. Using a data structure is like depending on an abstraction. It wraps up the tricky stuff in a more restrictive, but simpler API.

Lazy initialization

I’ll just quickly point out that lazy initialization is another form of the the check-then-set race condition. The ||= operator effectively expands to

@logger ||= Logger.new

# expands to 

if @logger == nil
  @logger = Logger.new
end

@logger

Look at the expanded version and imagine where the interleavings could occur. With multiple threads and no synchronization, it’s definitely possible for that @logger to be initialized twice. Again, initializing a Logger twice may not be a problem in this case, but I have seen bugs like this in the wild that do cause issues.

Reflections

I want to leave you with some lessons at the end of all this.

4 out of 5 dentists agree that multi-threaded programming is hard to get right.

At the end of the day, all that the GIL guarantees is that MRI’s native C implementations of Ruby methods will be executed atomically (but even this has caveats). This behaviour can sometimes help us as Ruby developers, but the GIL is really there for the protection of MRI internals, not as a dependable API for Ruby developers.

So the GIL doesn’t ‘solve’ thread-safety issues. As I said, getting multi-threaded programming right is hard, but we solve hard problems every day. One way that we work with hard problems is with good abstractions.

For example, when I need to do an HTTP request in my code, I need to use a socket. But I don’t usually use a socket directly, that would be cumbersome and error-prone. Instead, I use an abstraction. An HTTP client provides a more restrictive, simpler API that hides the socket interactions and associated edge cases from me.

If multi-threaded programming is hard to get right, maybe you shouldn’t be doing it directly.

“If you add a thread to your application, you’ve probably added five new bugs in doing so.”

Mike Perham

We’re seeing more and more abstractions around threads. An approach that’s catching on in the Ruby community is the Actor model of concurrency, with the most popular implementation being Celluloid. Celluloid provides a great abstraction that marries concurrency primitives to Ruby’s object model. Celluloid can’t guarantee that your code will be thread-safe or free from race conditions, but it wraps up best practices. I encourage you give Celluloid a try.

These problems that we’re talking about aren’t specific to Ruby or MRI. This is the reality of programming in a multi-core world. The number of cores on our devices is only going up, and MRI is still figuring out its answer to this situation. Despite its guarantees, the GIL’s restriction on parallel execution seems like the wrong direction. This is part of MRI’s growing pains. Other implementations, like JRuby and Rubinius, are running truly parallel with no GIL.

We’re seeing lots of new languages that have concurrency abstractions built-in at the core of the language. The Ruby language doesn’t have any of this, at least not yet. Another benefit of relying on abstraction is that the abstractions can improve their implementation, while your code remains unchanged. For example, if the implementation of Queue switched from relying on locks to using lock-free synchronization, your code would reap the benefits without any modification.

For the time being, Ruby developers should educate themselves about these issues! Learn about concurrency. Be aware of race conditions. Thinking about code as interleavings can help you reason about race conditions.

I’ll leave off with a quote that’s influencing much of the work being done in the larger field of concurrency today:

Don’t communicate by sharing state; share state by communicating.

Using data structures for synchronization supports this; the Actor model supports this. This idea is at the core of the concurrency model of languages like Go, Erlang, and others.

Ruby needs to look to what’s working in other languages and embrace it. As a Ruby developer, you can do this today by trying out and supporting some of these alternative approaches. With more people on board, these approaches could become the new standard for Ruby.

Thanks to Brian Shirai for reviewing a draft of this.

HTML5 and CSS3 2nd Ed, OpenGL ES 2 for Android in print

HTML5 and CSS3 2nd Ed now in beta, OpenGL ES 2 for Android in print

How do I benchmark Ruby code?

Send to Kindle

How do I benchmark Ruby code?

This guest post is by Jesse Storimer. He’s the author of Working With Unix Processes, a gentle introduction to Unix system programming for Ruby programmers. Jesse has been programming Ruby since joining Shopify in 2008 and is still going strong, always looking for a chance to dig lower down into the stack. He lives way in the backwoods of southern Ontario, Canada with his wife and two daughters. Jesse blogs at jstorimer.com and has authored a few other books for Ruby developers.

Jesse Storimer So you’ve got some Ruby code and you want to make it faster. Maybe you’ve already got a new implementation in mind, or maybe you’re still cooking that up. But how do you make certain that your new implementation is faster?

Science, of course! Ruby’s standard library comes with a benchmarking library fit for measuring the execution time of your Ruby code. The Benchmark module offers several different ways for you to benchmark your code. I’ll take you through the different options and their use cases.

Getting started

The Benchmark module is in the standard library, so you don’t need to install any gems to get it. Here’s the documentation from the standard library.

The simplest way to measure your Ruby code is with Benchmark.measure.

require 'benchmark'
require 'bigdecimal/math'

# calculate pi to 10k digits
puts Benchmark.measure { BigMath.PI(10_000) }

This will return something that looks like this:

  0.310000   0.040000   0.350000 (  0.339958)

With no context, these might look like magic numbers. Here’s what they mean:

Benchmark numbers breakdown

Generally, the number farthest to the right is the most important one. It tells how long it actually took to perform the operation. If you’re curious about why the clock time is so high, the other numbers can help you drill down to see if you’re spending time in system functions or your own code.

Now that you know what those magic numbers mean, we can move on to the core Benchmark API. The truth is that I rarely use the measure method on its own. It only prints the benchmark for a single block of code. The most common way to use Benchmark is to compare the execution time of different approaches to the same problem.

Benchmark has some built-in methods for this exact purpose.

Benchmark#bm

This method lets you define several blocks of code to benchmark, then prints the results side-by-side in the same format you saw earlier.

require 'benchmark'

iterations = 100_000

Benchmark.bm do |bm|
  # joining an array of strings
  bm.report do
    iterations.times do
      ["The", "current", "time", "is", Time.now].join(" ")
    end
  end

  # using string interpolation
  bm.report do
    iterations.times do
      "The current time is #{Time.now}"
    end
  end
end

This will print the following result:

       user     system      total        real
   0.540000   0.010000   0.550000 (  0.556572)
   0.410000   0.010000   0.420000 (  0.413467)

Notice that this is the same format I outlined earlier, but now you have little hints about each of the numbers.

The core API here is this:

Benchmark.bm do |bm|
  bm.report { first_approach }
  bm.report { alternative_approach }
end

You call the Benchmark#bm method passing a block. The block variable is a special object provided by Benchmark. It gives you a report method that you call with the block of code that you want to measure. Benchmark then runs both blocks of code and prints their execution times side-by-side.

A note about iterations: Often, when doing benchmarks that test code that executes very quickly, you need to do many iterations to see a meaningful number. In this case, I did 100,000 iterations of each variant just to get the execution time up to half a second so I could grasp the difference.

Labels

In that last benchmark, I buried some comments in the source that said what each block of code was doing. That’s not so helpful when looking at the results! Benchmark allows you to pass in a label to the report method that will be printed along with the results.

require 'benchmark'

iterations = 100_000

Benchmark.bm(27) do |bm|
  bm.report('joining an array of strings') do
    iterations.times do
      ["The", "current", "time", "is", Time.now].join(" ")
    end
  end

  bm.report('string interpolation') do
    iterations.times do
      "The current time is #{Time.now}"
    end
  end
end

I’ve now removed the comments describing the blocks and pass them in to the report method as an argument. Now the output describes itself:

                                  user     system      total        real
joining an array of strings   0.550000   0.010000   0.560000 (  0.565089)
string interpolation          0.410000   0.010000   0.420000 (  0.416324)

There’s one more important change I made in that last example that may have gone unnoticed. I passed 27 as an argument to the Benchmark.bm method. This signifies how much padding the header labels should have in the result output. If you pass labels to report, but don’t set this value high enough, your output won’t line up properly.

Let’s see an example with no argument passed to Benchmark.bm.

       user     system      total        real
joining an array of strings  0.520000   0.010000   0.530000 (  0.541942)
string interpolation  0.390000   0.010000   0.400000 (  0.394111)

That’s certainly not right. Make sure you pass a value that’s greater than the length of your longest label. That’s the happy path.

Benchmark#bmbm

The Benchmark#bm you just saw is really the core of Benchmark, but there’s one more method I should mention: Benchmark#bmbm. That’s right it’s the same method name, repeated twice.

Sometimes, with a benchmark that creates a lot of objects, the results start to get skewed because of interactions with Ruby’s memory allocation or garbage collection routines. When creating a lot of objects, one block may need to run garbage collector, while the other doesn’t; or just one block may get stuck with the cost of allocating more memory for Ruby to use.

In this case, the benchmark can produce unbalanced results. This is when you want to use Benchmark#bmbm.

The method name is suitable because it actually benchmarks your blocks of code twice. First, it runs the code as a ‘rehearsal’ to force any initialization that needs to happen, then it forces the GC to run, then it runs the benchmark again ‘for real’. This ensures that the system is fully initialized and the benchmark is fair.

This last example benchmark allocates a lot of objects. When this runs at the rehearsal stage, Ruby has to allocate more memory to make room for all the objects. Then when the ‘real’ benchmark happens, the memory is already available and just the actual implementation is tested.

require 'benchmark'

array = Array(1..10_000_000)

Benchmark.bmbm(7) do |bm|
  bm.report('reverse') do
    array.dup.reverse
  end

  bm.report('reverse!') do
    array.dup.reverse!
  end
end

And here’s the result:

Rehearsal --------------------------------------------
reverse    0.020000   0.020000   0.040000 (  0.050908)
reverse!   0.030000   0.020000   0.050000 (  0.048042)
----------------------------------- total: 0.090000sec

               user     system      total        real
reverse    0.010000   0.000000   0.010000 (  0.015385)
reverse!   0.030000   0.000000   0.030000 (  0.023973)

Notice the discrepancy between the rehearsal and the benchmark! Thanks bmbm!

Conclusion

When you want to try your hand at speeding up some of your Ruby code, make sure that you measure, measure, measure to prove that your new implementation is faster than the old one. This great little benchmarking library ships with Ruby right in the standard library, so there’s no excuses!

I hope you found this article valuable. Feel free to ask questions and give feedback in the comments section of this post. Thanks!

Technorati Tags: , , , ,


(Powered by LaunchBit)

Ruby 2.0.0 Now Default on All New Ruby Applications

Heroku provides an opinionated platform in order to help you build better applications. We give you a default version of Ruby to get you started, and give you a way to declare your version for total control. In the past creating an application would give you 1.9.2, starting today the default is 2.0.0.

Ruby 2.0.0 is fast, stable, and works out of the box with Rails 4. Applications running on 2.0.0 will have a longer shelf life than 1.9.3, giving you greater erosion resistance.

Default Behavior

If you have a previously deployed app it will continue to use Ruby 1.9.2, any new applications will run on 2.0.0. Heroku is an erosion resistant platform, which means we will not change a major or minor version of Ruby on your app without you taking action.

Setting your Ruby Version

In addition to providing a default version of Ruby, you have the ability to specify your version of Ruby in your Gemfile:

ruby '2.0.0'

While you can prototype on the default Ruby, we recommend explicitly setting your version on all production applications. When you specify the Ruby version in your codebase, you get the exact same version: across every developer and across every app. This means any new developers on your team, any new staging apps you set up on Heroku and any forked apps will have the same version. If your app needs consistency: define your Ruby version.

Ruby 2.0

Ruby 2.0 includes copy on write friendly garbage collection which can reduce memory usage in a forking server such as Unicorn. Ruby 2.0.0 has faster code loading which means large frameworks such as Rails start much faster. Ruby 2.0.0 is mostly backwards compatible with 1.9.3 and at Heroku our developers already run Ruby 2.0.0.

Using the latest stable version of Ruby has advantages for the community as well as for application's performance. In the past some Rubyists have resisted upgrading. This resulted in libraries needing to support multiple versions of Ruby for long periods of time, and creating factions within the community. For instance while Ruby 1.9.3 was released in 2011 there are many developers who are just now upgrading from Ruby 1.8.7 which, was released in 2008. We have encouraged developers to run Ruby 2.0.0 on our platform by making the preview available, and the GA version available on launch day. By setting the default version to 2.0.0 we hope to encourage more developers to run on the most recent stable Ruby version.

Stability, speed, and community are all good aspects to support, but we also care about application maintainability. At the end of this month Ruby 1.8.7 will reach end-of-life. Maximize the life of your application and simplify your upgrade to 2.1.0, coming in December, by using the most recent release.

Conclusion

Ruby at Heroku provides both defaults and flexible choices. You can explicitly declare a Ruby version or accept a stable, default version. Sometimes you may just need something to work, and others you want to enforce dev/prod parity between developers. By supporting a default Ruby you can do either.

Thanks to Japan based Herokai: Ayumu Aizawa, Yukihiro "Matz" Matsumoto, Koichi Sasada, and Nobuyoshi Nakada, for working with us to push our defaults forward. Ruby Core is excited to see Heroku support the new 2.0 default, we hope you are too. Try it on Heroku and let us know what you think: @heroku.

#417 Foundation

ZURB’s Foundation is a front-end for quickly building applications and prototypes. It is similar to Twitter Bootstrap but uses Sass instead of LESS. Here you will learn the basics of the grid system, navigation, tooltips and more.

Introducing Notification Center

Change is a constant. At Heroku, we often deliver important information to users about changes and events on the platform, their apps and their accounts. We use a variety of media to keep users informed about these changes, including email, Twitter, the changelog and the blog.

To help provide more direct and relevant information, we've added a new feature to Dashboard called Notification Center. We'll be using the Notification Center to keep you informed of important events affecting you and your apps. When new notifications arrive, you'll see a badge in Dashboard's header.

If you log in today, you'll see something that looks like this:

We'll be carefully curating the events we post to make sure they don't become too noisy. Here's a list of some of the things we're planning to notify about to start:

  • Billing changes such as 2X Dyno pricing going into effect.
  • New platform defaults that affect your applications.
  • Important framework security vulnerabilities that affect your apps.
  • Account alerts, such as expired credit card information or overdue invoices.
  • Changes in add-on state, such as an add-on you're using leaving its beta phase.

We hope you enjoy having notifications available on Dashboard. We're always looking for better ways to keep you up to date with changes that affect your apps on the platform, so let us know where we can help you out.

State of The MSTWJS Union, June 2013

Here is the state of the Master Space and Time With JavaScript Union as a I currently understand it.

First, you can, you know, buy the book. Please.

An update to the Ember book should be going out next Monday or so. It has about 10-15 page chapter walking through a routing example with outlets and nested routes and the like. That’s puts the Ember PDF at just over 90 pages (including the back matter and contents and stuff), which compares favorably with the lengths of the other three books (97, 97, and 120, I think).

I think there are still a few things missing from the Ember book.

  • More on views and handlebar helpers
  • Ember data details
  • Ember-testing details
  • Anything else the Ember team adds before 1.0 (async routing, for example)
  • I’d like to deal with some real-world examples, at least briefly, of things like authentication

This points to a final page count roughly in the range of the backbone book, about 120 pages or so. Actually, probably more. Sheesh.

What’s tricky about this is that ember-data and ember-testing are still not quite done enough to write about them without risking throwing everything out and starting over, so it’s hard to give a final schedule.

The other books are quiet at the moment, though the Backbone book could stand an edit.

Thinking Ahead

Meantime, there’s a slow but steady trickle of requests for a MSTWJS Book 5: Angular. (A five part trilogy would make me feel like Douglas Adams)…

I’m genuinely not sure if I’m going to do this. The considerations are:

Opportunity. There’s clearly some space here for a book that really explains Angular. According to a Twitter poll — which I’m sure is totally reliable — the overwhelming majority of existing MSTWJS customers would expect to pay for a Book 5. This actually goes a long way toward making me think this is worth my time. Writing tech books is kind of a hobby for me, but I’d still like to feel that I can make a little bit of money from them.

On the other hand, I’ve been working on this book for two years now. That’s a long time in Internet years, and doing an Angular version probably means another three to six months of work. There are other things I want to write, and it wouldn’t kill me to blog regularly again. (Actually, that implies that I once blogged regularly, which is not really true.) I really want to do this project book, and I’m starting to feel like I have new things to say about testing.

Anyway, right now I’m thinking that I’ll at least play with Angular a bit to see if I have any affinity for the tool at all. If I hate working with it, I’m not writing about it. If it passes that hurdle, then we’ll see.

If I do it, the likely scenario would be — don’t hold me to this, I’m just thinking out loud:
* Priced at $7 or $9 based on length
* Existing 4 book bundle owners would get a discount, possibly a limited time discount depending on what I can do via DPD.
* At that point, new customers would get a five book bundle. I might raise all prices at that point — the hypothetical five book bundle would be nearly 600 pages. Not sure what that pricing looks like yet. $9 per book with a $25 bundle is one possibility.

Please let me know if you have thoughts about this — my perception of people’s willingness to buy an Angular book in this series is a major factor in whether I do it.

And, oh yeah, buy the book.

Thanks.

Historical Uptime on Status Site

Until now, Heroku Status has been focused primarily on present platform health – providing current status, uptime for the current month, and recent incident history. Today we're announcing an addition to our status site: a dedicated page to view historical uptime. The new uptime page provides a longer-term perspective on Heroku uptime and incidents – perspective that is critical for transparency and continued trust in the Heroku platform.

The new uptime page covers both the US and Europe regions for visibility into uptime where your apps are hosted. This was a top-requested feature with the recent launch of Heroku's Europe region.

The uptime page displays per-month uptime going back up to one year for both the US and Europe regions. To provide a view of historical incidents as well as historical uptime, it also visualizes the occurrence and duration of major and minor incidents by day. This page is designed to provide a clear and transparent view into uptime and incident occurrence over time.

You can find out more about Heroku Status, how we calculate uptime, and other details in the Dev Center.

Building Apps Efficiently on Heroku

Whether you’re building your initial prototype or running a large scale profitable business, there will be times where you will have questions about building, maintaining, or troubleshooting your application. One of our goals is to help make your business successful by empowering you to build quality software with best practices, clear documentation on a stable erosion-resistant platform. When in doubt, there are several channels here at Heroku available to help you get the support you need.

Getting Started

Brand new to development or just new to Heroku there’s a place for you in the Dev Center. As you’re getting started you likely want to setup your application so you can get better visibility. Several tools are recommended, including add-ons for monitoring, add-ons for logging and native tools such as log2viz that provide visibility into application performance and issues.

Throughout the app development process, you will want to take into consideration best practices for application architecture and scaling, The Twelve Factor App provides the recommended methodology for building software-as-a-service apps on Heroku.

Ready to Launch

Moving from development to production is a critical stage. When you’re developing you often don’t worry about uptime or bugs, but in production you want to take extra steps. The best place to start is through Heroku’s built in production check which runs your app through a checklist for maximizing uptime and ensuring optimal performance. Items in the production check include using Cedar, dyno redundancy, DNS & SSL, production databases and appropriate visibility and monitoring.

I’m stuck, now what?

When additional support is required, Heroku’s Help App provides a guided experience for accessing documentation and resources to get answers quickly. Help App aggregates content from both Heroku documentation and community discussions forums like Stack Overflow where Heroku engineers are very active. If questions are left unanswered, users have the ability to get in touch with Heroku support engineers from Help App. While free standard support hours are 9am–9pm ET without an SLA, Premium Support offers 24×7 coverage with 2-hour response time (this is the maximum; most premium support tickets are answered within a few minutes). When you aren’t able to find the answer yourself, Heroku support engineers are here to help.

Common issues that support can assist with include setting up DNS with root domains, securing a site with SSL, and migrating data between database plans. We are also able to help guide customers with more advanced needs such as difficult scaling techniques, app and database performance. When sending a support ticket, it’s a good idea to first perform the steps outlined in the above sections and explain what you’ve already tried.

I need more

In addition to Premium Support, Heroku offers individualized attention and support to your app through a dedicated Heroku engineer, called a technical account manager. Technical account managers offer the advantage of someone having immediate context and background on your apps. They also review your apps end to end for architecture, configurations and optimizations you may not have considered and will make recommendations on a regular basis.

Early access

Premium support services give you first access to new features that might be of help in making your app perform faster and more reliably, making teams of developers more productive. Some prior examples include early access to to 2X dynos, PostGIS and Fork and Follow before any were publicly announced.

We’re here to help

To learn more about best practices, guaranteed response times and support for critical apps, our customer advocacy team provides free introductory 1:1 assistance. Get in touch today.

Heroku Platform API Hack-a-thon June 20th in SF

The new Heroku platform API is out in public beta. Come join our API team for an API Hack-a-thon on June 20th at Heavybit Industries (9th and Folsom) for an in-depth look. Doors open at 6:00p.

This hack-a-thon is not a competition, but an in-depth look at the beta release – a chance for you to ask questions and provide feedback to the Heroku API team.

Heroku’s API lead, Wesley Beary, will start the evening with a live presentation on the design and possibilities of the platform API. We will then have until 10:00p to talk to Wesley and the rest of the API team to ask questions and hack on code as well as enjoy a little food and drink.

Space is limited, so register today.

Ruby Programming 43rd Batch: Registrations now open

Send to Kindle

Registrations are now open for RubyLearning’s popular Ruby programming course. This is an intensive, online course for beginners that helps you get started with Ruby programming.

Course Fee

Please create a new account first and then pay US$ 63.95 by clicking on the PayPal button Paypal


Download ‘Advice for Ruby Beginners’ as a .zip file.

Here is what Demetris Demetriou, a participant who just graduated, has to say – “When I joined this course I was sceptical about how useful this course would be for me instead of reading material and watching videos on YouTube and thus saving money. After the course started I realised how valuable this course was. In the past I had read many Ruby books over and over, but never got into really getting practical with it and never had confidence in it. Lots of theory but couldn’t use it. I feel that the exercises in this course and the support, monitoring from our mentor Victor, made the huge difference that all books in the past didn’t. It wasn’t about reading lots of books, but simply few things and get practical and understand them well. I feel I learnt a lot and I’m coming back for more to rubylearning.org Thanks a lot Victor and Satish and all the other Rubyists who gave us today’s Ruby.”

What’s Ruby?

Ruby

According to http://www.ruby-lang.org/en/ – “Ruby is a dynamic, open source programming language with a focus on simplicity and productivity. Ruby’s elegant syntax is natural to read and easy to write.”

Yukihiro Matsumoto, the creator of Ruby, in an interview says –

I believe people want to express themselves when they program. They don’t want to fight with the language. Programming languages must feel natural to programmers. I tried to make people enjoy programming and concentrate on the fun and creative part of programming when they use Ruby.

What Will I Learn?

In the Ruby programming course, you will learn the essential features of Ruby that you will end up using every day. You will also be introduced to Git, GitHub, HTTP concepts, RubyGems, Rack and Heroku.

Depending on participation levels, we throw a Ruby coding challenge in the mix, right for the level we are at. We have been known to give out a prize or two for the ‘best’ solution.

Who’s It For?

A beginner with some knowledge of programming.

You can read what past participants have to say about the course.

Mentors

Satish Talim, Michael Kohl, Satoshi Asakawa, Victor Goff III and others from the RubyLearning team.

Dates

The course starts on Saturday, 29th June 2013 and runs for seven weeks.

RubyLearning’s IRC Channel

Most of the mentors and students hang out at RubyLearning’s IRC (irc.freenode.net) channel (#rubylearning.org) for both technical and non-technical discussions. Everyone benefits with the active discussions on Ruby with the mentors.

How do I register and pay the course fees?

  • The course is based on the The Ultimate Guide to Ruby Programming eBook. This book is priced at US$ 9.95
  • You can pay either by Paypal or send cash via Western Union Money Transfer or by bank transfer (if you are in India). The fees collected helps RubyLearning maintain the site, this Ruby course, the Ruby eBook, and provide quality content to you.

To pay the Course Fee:

Please create a new account first and then pay US$ 63.95 by clicking on the PayPal button Paypal

At the end of this course you should have all the knowledge to explore the wonderful world of Ruby on your own.

Here are some details on how the course works:

Important:

Once the course starts, you can login and start with the lessons any day and time and post your queries in the forum under the relevant lessons. Someone shall always be there to answer them. Just to set the expectations correctly, there is no real-time ‘webcasting’.

Methodology:

  • The Mentors shall give you URL’s of pages and sometimes some extra notes; you need to read through. Read the pre-class reading material at a convenient time of your choice – the dates mentioned are just for your guideline. While reading, please make a note of all your doubts, queries, questions, clarifications, comments about the lesson and after you have completed all the pages, post these on the forum under the relevant lesson. There could be some questions that relate to something that has not been mentioned or discussed by the mentors thus far; you could post the same too. Please remember that with every post, do mention the operating system of your computer.
  • The mentor shall highlight the important points that you need to remember for that day’s session.
  • There could be exercises every day. Please do them.
  • Participate in the forum for asking and answering questions or starting discussions. Share knowledge, and exchange ideas among yourselves during the course period. Participants are strongly encouraged to post technical questions, interesting articles, tools, sample programs or anything that is relevant to the class / lesson. Please do not post a simple "Thank you" note or "Hello" message to the forum. Please be aware that these messages are considered noises by people subscribed to the forum.

Outline of Work Expectations:

  1. Most of the days, you will have exercises to solve. These are there to help you assimilate whatever you have learned till then.
  2. Some days may have some extra assignments / food for thought articles / programs
  3. Above all, do take part in the relevant forums. Past participants will confirm that they learned the best by active participation.

Some Commonly Asked Questions

  • Qs. Is there any specific time when I need to be online?
    Ans. No. You need not be online at a specific time of the day.
  • Qs. Is it important for me to take part in the course forums?
    Ans. YES. You must Participate in the forum(s) for asking and answering questions or starting discussions. Share knowledge, and exchange ideas among yourselves (participants) during the course period. Participants are strongly encouraged to post technical questions, interesting articles, tools, sample programs or anything that is relevant to the class / lesson. Past participants will confirm that they learned the best by active participation.
  • Qs. How much time do I need to spend online for a course, in a day?
    Ans. This will vary from person to person. All depends upon your comfort level and the amount of time you want to spend on a particular lesson or task.
  • Qs. Is there any specific set time for feedback (e.g., any mentor responds to me within 24 hours?)
    Ans. Normally somebody should answer your query / question within 24 hours.
  • Qs. What happens if nobody answers my questions / queries?
    Ans. Normally, that will not happen. In case you feel that your question / query is not answered, then please post the same in the thread – “Any UnAnswered Questions / Queries”.
  • Qs. What happens to the class (or forums) after a course is over? Can you keep it open for a few more days so that students can complete and discuss too?
    Ans. The course and its forum is open for a month after the last day of the course.

Remember, the idea is to have fun learning Ruby.

Technorati Tags: , , ,


(Powered by LaunchBit)