About concept47

Ruby/Rails/Jquery/MySql/PostgresSQL hacker. Wannapreneur. Love to build beautiful things.

Is Ruby pass-by-reference or pass-by-value?

I was confused by Ruby’s variable assignment paradigm for a while, and even after reading this Stackoverflow thread and checking out out other threads about the same thing I was no closer to understanding it clearly. And in the words of the great Albert Einstein …

“if you can’t explain it simply you don’t understand it well enough”

I eventually figured it out by reading page 53-54 of what I think is the best Ruby book on the market right now, turns out its actually pretty simple to understand.

Ruby ALWAYS passes references to objects on assignment, BUT some types in ruby are stored in variables as immediate values because they are immutable.

For example (you can try these out in irb)

me = we = “we”
me #=> “we”
we #=> “we”
me.upcase!
me #=> “WE”
we #=> “WE”

me = we = [1, 2, 3]
we #=> [1, 2, 3]
me #=> [1, 2, 3]
we << 4
we #=> [1, 2, 3, 4]
me #=> [1, 2, 3, 4]

Ruby does this for all its types, but with primitives that are immutable, namely integers, symbols, nil, and the booleans true and false, it takes a shortcut and actually stores the value IN the variable itself, because … what are you going to do? change an immutable object? :)

Pretty clever when you think about it IMO.

Controlling Elasticsearch memory usage on os x

By default, Elasticsearch will use between 256MB and 1GB of memory. On my dev environment, memory is a premium and I don’t really have a lot of data to index and play with so I’d prefer this to be closer to 256m

To change this, navigate to
/usr/local/Cellar/elasticsearch/x.xx.x/bin

(where x.xx.x is the Elasticsarch version number)
open up elasticsearch.in.sh

then replace the memory size in the following lines

if [ "x$ES_MIN_MEM" = "x" ]; then
    ES_MIN_MEM=256m
fi
if [ "x$ES_MAX_MEM" = "x" ]; then
    ES_MAX_MEM=1g
fi

It is recommended that you set both ES_MIN_MEM and ES_MAX_MEM to the max size you want so that Elasticsearch doesn’t have to pause to resize memory, which can affect performance.

from the comments in that file …

min and max heap sizes should be set to the same value to avoid
stop-the-world GC pauses during resize, and so that we can lock the
heap in memory on startup to prevent any of it from being swapped
out.

I upgraded to Ruby 2.1.0 and all I got was this lousy T-shirt …

Ruby 2.1.0 was released about 2 weeks ago, and after seeing a notable speed performance improvement with my Rails app when going from 1.9.3 to 2.0.0 I was excited to see if the same would happen with Ruby 2.1.0.

I quickly ran another set of very casual tests, mainly running test suites and noting startup times of rails commands and rake tasks at the command line. What I saw was a 20% improvement in those tasks. Nothing to sneeze at …

Excited, I rushed to upgrade my tiny Rails app to ruby 2.1.0 and after doing it I tracked the difference in New Relic

This was my result (deployment happened about 18:00 on December 25th, app is setup to run with one puma worker and 8-16 threads proxied to nginx)

New Relic graph after upgrading to Ruby 2.1.0 (18:00 on the graph)As you can see, there wasn’t much of an improvement in performance at all. In fact here is the graph after a full day of running in the wild.

New Relic graph of my app after a full day of running with Ruby 2.1.0

 

So while you might get better startup times on Rails tasks, you probably won’t see too much of a speed boost on your servers.

Improved GC

What I found interesting, though, is the improved garbage collection. The brown part of the graph (GC execution) almost completely disappears in ruby 2.1.0. And its no wonder, a lot of work went into improving Garbage collection in ruby 2.1.0

The garbage collector in Ruby 2.1 implements a form of generational garbage collection, with Ruby calling their implementation RGenGC (Restricted Generational Garbage Collection).  This replaces the “Mark & Sweep” implementation used in previous versions of Ruby

Using RGenGC provides high compatibility with existing extensions while still bringing performance improvements.  Popular objects Array, String, Hash, Object, and Numeric are Write-Barrier protected, thus able to take advantage of the RGenGC system

The moral of the story? Ruby 2.1.0 has a small performance boost over Ruby 2.0 and upgrading to it should give you a bit of a boost with your Rails app, more if its a pretty big app with non-trivial time spent doing GC.

PS: Brian Hempel has created an awesome site that benchmarks ruby versions using Rails. His results are in line with what I found
PS2: Sorry there wasn’t actually a T-shirt, I just liked the title

fixing Gitbox on Apple OS X Mavericks

gitbox

As soon as Mavericks was released I rushed to install it, and for the most part, the upgrade went smoothly … with one exception. Gitbox wouldn’t start.

I upgraded XCode, uninstalled, and reinstalled it, then restarted OS X multiple times, but each time I clicked on the icon in the dock, it would light up but the familiar gitbox window with all my repos would not appear.

For a while I made do with Tower (which I started to like after a while), but eventually I found this little nugget of a tweet

Essentially, to get gitbox working again, you need to open up terminal and just type

defaults delete com.oleganza.gitbox

Hit enter and that’s it. When you open up Gitbox again, it will start up, but all your repos will be gone. Just re-add them.

 

Product idea: iphone music auto resume when changing music sources

tumblr_mh1nqcop7v1ri78hlo1_500

Wouldn’t it be cool if when you disconnected your headphones from your iphone and plugged it into an aux jack from your car, the music just continued playing?

I face this issue each time I’m coming from the gym, in the zone listening to a song, then I get into my car and have to change the connections. I absolutely HATE having to bring up the music app and hit play to keep going. It would be amazing if for 5/10 seconds after you disconnect the headphone jack, the iphone just auto resumes playing whatever was playing before, if you plug it into something else. The interesting thing is that if you connect to a bluetooth device it already does this by default (continues playing from where you left off), this would just be a more explicit extension of that user experience pattern.

how to know if your 2011 macbook pro can run with 16GB of ram

2012 and newer macbook pros can run with 16GB of RAM, but 2010 and 2011 models are not supposed to be able to do the same … allegedly.

Turns out that even though the apple tool that tells you the maximum amount of memory you can run with the 2011 models is 8GB, you might still be able to actually upgrade to 16GB, if your cpu is an i7 27xxQM or 28xxQM processor.

Drop into your command line and run this command
> sysctl -n machdep.cpu.brand_string
Intel(R) Core(TM) i7-2760QM CPU @ 2.40GHz

As you can see, in my case, the cpu is the correct one for an upgrade.

The RAM in these is usually 1333 MHz PC3-10600 DDR3 SDRAM but for the upgrade you’ll want 1600 MHz PC3-12800 DDR3 SDRAM

enjoy
PS: Of the 2010 models, only the 13″ models can take 16GB of RAM, my source for all this information was the macbook pro wikipedia page.

 

Does your product fit into my life and make it awesome?

I absolutely love this Apple ad …

Whenever it comes on, I completely stop whatever it is I’m doing and watch it.

There is another ad I love almost as much, and its this one by google

What I love about these ads is how they tell you a story.

One in which the product is just a supporting actor.

A story of how their technology fits into your life and makes it awesome.

You see, some people can relate to wanting to have a cooler phone than the other person.

Some people can relate to having a more expensive car or getting a table at that impossible-to-get-reservations restaurant.

Yeah, people get off on having stuff that no-one else has.

But that is a small subset of human aspiration.

The things people really want are usually much simpler than that.

People want to see things they’ve never seen before, go places they’ve never been, hang out with people they like, eat awesome food, have someone think they’re attractive … even sexy … then share all those with people they know

People want to make their friend laugh, have them think they’re a riot.

People really just want simple things things most of the time.

So you can actually make your product huge by showing people how it helps them do the little things.

How you seamlessly fit into their life and make it awesome.

If you can do that … You’ve won.

Thats how facebook got big.

Thats how instagram got big.

Thats how the ipad got big.

They are personal awesomeness force multipliers.

As an example airbnb.com, shows you breathtakingly beautiful places that it has listed when you arrive at the site.

They fade in and out in the background.

Pazin, Croatia. Barcelona, Spain. Copenhagen, Denmark.

Beautiful homes, in beautiful places. for $80 a night!

It makes your imagination run wild. You start to wonder …

“A plane ticket would be … ,”

“If I stayed 2 nights I could do this for less than …”

You start to create your own story in your head. because you can’t help it, you’re human.

And without even seeing a single ad, you’re hooked.

Because airbnb can fit into your life and make it way awesome.

So the question if you’re a product maker is … Whats your story?

How does your thing seamlessly fit into my life and make it awesome?

Relevant: Want to Increase a Product’s Value by 2,706%? Give It a Story

Student loan debt, millenials and the sharing economy

11studentloans-articleLarge

RE: Student Debt Slows Growth as Young Spend Less — NYTimes

Earlier this year there was a lot of hand wringing about why younger kids aren’t buying cars, or houses etc, and the consensus seemed to be that the financial turmoil of 2007/8, and its cavalcade of side effects was the reason, that as the economy improved, things would go back to normal. The writer, wondered, however …

“But what if these assumptions are simply wrong? What if Millennials’ aversion to car-buying isn’t a temporary side effect of the recession, but part of a permanent generational shift in tastes and spending habits? It’s a question that applies not only to cars, but to several other traditional categories of big spending—most notably, housing. And its answer has large implications for the future shape of the economy—and for the speed of recovery.”

It seems like that is exactly the case, and the big catalyst for this change is crushing Student loan debt, coupled with the credit crunch, and slow job market from the near-financial- apocalypse of 2007/8

“It is a new thing, a big social experiment that we’ve accidentally decided to engage in,” said Kevin Carey, the director of the Education Policy Program at the New America Foundation, a research group based in Washington. “Let’s send a whole class of people out into their professional lives with a negative net worth. Not starting at zero, but starting at a minus that is often measured in the tens of thousands of dollars. Those minus signs have psychological impact, I suspect. They might have a dollars-and-cents impact in what you can afford, too.”

What trips me out is how because of this … new ways of thinking about ownership have been spawned that have the potential to reshape our world going forward.

Car2go, zipcar, airbnb, uber, Spotify, rdio … millenials aren’t buying to own any more, they’re renting/sharing and the ramifications of this could be massive.

In the end, its really just amazing how the world seems to undergo these seismic changes while nobody is paying attention, and then, just like that … everything changes.

Also Read: The Cheapest Generation 

Showing better highlighted search result fragments with Elasticsearch

Elasticsearch has a pretty awesome highlighting feature, but it comes with a major deficiency. When it truncates your document/string, it gives you no indication that it has done so.

Take a look at this screen shot

As you can see the text (bolded behind the dropdown of results) is truncated in the results in the dropdown itself, but there’s no indication that is what has happened.

Doesn’t seem like a big deal, but for the perfectionists and craftsmen out there, this has to make you itch right? How is someone to know that there is more to that fragment of text that what they’re seeing?

Well, heres some ruby code to the rescue. Throw it in a helper and call it in your view or wherever

1
2
3
4
5
6
7
8
9
10
11
12
  def ellipses_for_highlights(params_highlight, params_original)
    # have to do this because highlighted stuff from ES has a trailing space for whatever reason
    stripped_highlighted_item = strip_tags(params_highlight).rstrip
    # if the beginning of the highlighted text doesn't match the original it has been clipped
    tmp = params_original =~ /#{stripped_highlighted_item}/
    front_ellipsis = tmp != 0
    # if the last 10 characters of the highlighted text don't match the original, same deal
    back_ellipsis = last_string_chars(stripped_highlighted_item, 10) != last_string_chars(params_original, 10)
 
    highlighted_item = front_ellipsis ? "... " + params_highlight : params_highlight
    highlighted_item = back_ellipsis ? highlighted_item + " ..." : highlighted_item
  end

Link to github gist here

to use this, just pass in the highlighted string from elasticsearch and the original string for comparison.
so something like this

1
    ellipses_for_highlights(item.highlight.name.first, item.name)

and you’ll get something like this

It will only truncate on the front or back of the string if elasticsearch only truncated at that spot, in addition to truncating on both ends if it realizes that elasticsearch did too. Better, right?

Couple of things to note.
- This will only work cleanly if you have  :term_vector set to “with_postions_offsets” in your mapping. This enables elasticsearch break the fragment on words vs truncating in the middle of a word. If you have it turned off (i.e you’re just using the plain highlighter), you’ll get something that looks more like this (notice how the truncation is happening in the middle of words)

- Also keep in mind that because of the behavior explained above when using term_vectors in your highlighting, the fragment_size will not match the number you specify exactly, makes sense (because it has to break on a word which can have be any number of characters in it), but its not described anywhere

Adding Autocomplete using elasticsearch

A commonly-requested feature in search applications is autocomplete or search suggestions. The basic idea is to give users instant feedback as they’re typing. Implementations of this feature can vary — sometimes the suggestions are based on popular queries (e.g., Google’s Autocomplete), other times they may be previews of results (e.g., Google Instant). The suggestions may be relatively simple, or they can be extremely complex, taking into account things like the user’s search history, generally popular queries, top results, trending topics, spelling mistakes, etc. Building the latter can consume the resources of a company the size of Google, but it’s relatively easy to add simple results-based autocomplete to an existing elasticsearch search application.

Read More … 

How I became a scientist (quote)

My mother made me a scientist without ever intending to.
Every other Jewish mother in Brooklyn would ask her child after school, “So? Did you learn anything today?”
But not my mother …
“Izzy,” she would say, “did you ask a good question today?”
That difference – asking good questions – made me become a scientist.
— Isidor Isaac Rabi, Nobel laureate

Found this gem on the 37 Signals blog

If you’ve ever had ANYTHING to Do with Rails. ever. Please read this now.

What The Rails Security Issue Means For Your Startup!

There are many developers who are not presently active on a Ruby on Rails project who nonetheless have a vulnerable Rails application running on localhost:3000.  If they do, eventually, their local machine will be compromised. (Any page on the Internet which serves Javascript can, currently, root your Macbook if it is running an out-of-date Rails on it. No, it does not matter that the Internet can’t connect to your localhost:3000, because your browser can, and your browser will follow the attacker’s instructions to do so. It will probably be possible to eventually do this with an IMG tag, which means any webpage that can contain a user-supplied cat photo could ALSO contain a user-supplied remote code execution.)

tracking down *exactly* where a Ruby object method is defined

Ever spent way longer than you would have liked trying to find out exactly where a particular Ruby object method is defined, especially in something like Rails where a method could have been included from a plugin, gem, helper, or otherwise metaprogrammed in?

Well with Ruby 1.9.3 … you can now do this

Post.first.method(:published?).source_location

and get this back

=> ["/Users/xxx/.rvm/gems/ruby-1.9.3-p362/gems/state_machine-1.1.2/lib/state_machine/machine.rb", 752]

Blew my mind, and I’ve been writing Ruby for almost 6 years now.

How to try out puma with Apache right now!

I came across puma reading Mike Perham’s blog and was instantly intrigued. Its a threaded server that runs using one copy of your app vs the way Passenger does it by spinning up about 2 or more copies of your app as processes forked from a parent process and distributing requests to each one in turn to keep them all busy.

The thing that jumped out at me was the promise of memory savings by going from 5-6 processes in memory to 1. I run a 768MB VPS with linode. With Passenger I was running 500-600MB RAM usage because of the distinct ruby processes that Passenger forks to handle requests to your server. (Each process was about 80M and I was running 5 or 6 of them)

There is no Apache documentation for proxying to puma, but after looking at this example by the Phusion guys about how to proxy Apache to Passenger Standalone, I figured out a nice little step-by-step way to quickly try out puma to see if you like it or not.

This assumes you’re already running Phusion Passenger with Apache in production

  1. gem install puma on your server, don’t add it to your gemfile
  2. Now mosey on over here and get Apache Proxy installed,
    /etc/apache2/mods-available/proxy.conf will probably already be there for you so all you’ll probably have to do is
    a2enmod proxy
    a2enmod proxy_http
    /etc/init.d/apache2 restart
  3. Alright, now go find your apache.conf or httpd.conf file and comment out all the passenger related stuff, things like …#LoadModule passenger_module /opt/ruby-enterprise-1.8.7-2010.02/lib/ruby/gems/1.8/gems/passenger-3.0.7/ext/apache2/mod_passenger.so

    #PassengerRoot /opt/ruby-enterprise-1.8.7-2010.02/lib/ruby/gems/1.8/gems/passenger-3.0.7

    #PassengerRuby /opt/ruby-enterprise-1.8.7-2010.02/bin/ruby

    … and other Passenger configuration directives (PassengerMinInstances for example)

  4. Now go find the file where you defined your virtual host, for me it was in
    /etc/apache2/sites-available/default
  5. Make it look like this (comment out all your other stuff for now, you can add other cool crap once you get it working)
    <VirtualHost *:80>
    ServerName www.yourapp.com
    DocumentRoot /path_to_your_app/public
    PassengerEnabled off
    ProxyPass / http://127.0.0.1:9292/
    ProxyPassReverse / http://127.0.0.1:9292/ #the trailing slashes here are VERY important
    </VirtualHost>
  6. now go to your app root and run
    puma -e production
  7. restart apache and navigate to your app and you should see it load right up

Couple of things to note

  • you will probably want to add a line to your production.rb that is simply
    config.threadsafe!
    It basically eager loads your app (vs autoloading the sections it needs) to help avoid problems with threading rails, you can learn more about config.threadsafe! in this very detailed post
  • I went from using close to 600MB of RAM to just 350MB and it was blazing fast!!!
    Then I moved over to using puma with nginx and Ruby 2.0.0 (post coming up) and it was even faster!
  • If you think you want to keep puma around then I encourage you to install the puma prerelease (currently 2.0.0.b4) by running
    gem install puma –prerelease
    once you do that, then you can run puma as a daemon by doing
    puma -d -e production
    otherwise you’ll have to have a terminal window open running it the way you run webrick/thin in dev
  • New relic reporting won’t work out the box unless you use the prerelease version
Thats it!
I hope you like puma as much as I do.