Monday, October 18, 2010

Hash#in_groups_of

Here is a quick and dirty snippet to distribute a Hash into an Array of mini-Hashes as an analogue to the Rails Array#in_groups_of method.


module MyHashExtensions
def in_groups_of(*args)
to_a.in_groups_of(*args).inject([]) do |accum, group|
accum << group.inject({}) {|acc, pair| pair.nil? ? acc : acc.merge(pair.first => pair.last)}
end
end
end
end

Hash.class_eval do # jam this into Hash however you wish!
include MyHashExtensions
end


Example usage:

{:a => 'b', :c => 'd', :e => 'f', :g => 'h', :i => 'j', :k => 'l', :m => 'n'}.in_groups_of(3)


gives...


[{:i=>"j", :e=>"f", :g=>"h"}, {:c=>"d", :a=>"b", :k=>"l"}, {:m=>"n"}]


I used this for Cassandra/Rails/Thrift experimentation today! Remember, the text buffer is your canvas. You are a software artist, whether you like it or not. Play with the code, and if someone doesn't like it, throat punch them.

Wednesday, January 13, 2010

Undoing Alias Method Chaining

This is more of a quick rant on AliasMethodChain in Rails than a tutorial... Metaprogramming in Rails is powerful. It is a wonderful way to build onto a framework which itself is built on top of Ruby via metaprogramming. I've seen and heard many arguments describing metaprogramming as the root of all evil. The chaos that it can cause when not structured is a terrible thing to behold, certainly.

I won't say much about how we handle our system extensions at Groupon, except, that it is very structured with a centralized place to discover all of the extensions to Rails internals in a single place (expect a more formal description of our process later from our Team!). Also, the extension points that we chose to use have been the parts of Rails which are the least subject to change (and have demonstrated the greatest resiliency and consistency over the last 3-4 years of active development).

Anyway, this morning, I ran into one of the (very few) cases where testing truly required assertions at various points in an alias_method_chain stack. As you can imagine, if you are alias_method_chaining ActiveRecord::Base#find, for example, you'll most likely have architected your system in such a way, that every link in the chain is standard, unalterable behavior (we absolutely do not muck with #find, btw. It is already an atrocious method). For these cases, I employ this little hack...


ActiveSupport::CoreExtensions::Module.class_eval do
def alias_method_chain_unlink(target, feature)

# Strip out punctuation on predicates or bang methods since
# e.g. target?_without_feature is not a valid method name.
aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
yield(aliased_target, punctuation) if block_given?

with_method, without_method = "#{aliased_target}_with_#{feature}#{punctuation}", "#{aliased_target}_without_#{feature}#{punctuation}"

alias_method target, without_method

case
when public_method_defined?(without_method)
public target
when protected_method_defined?(without_method)
protected target
when private_method_defined?(without_method)
private target
end
end
end

Notice its a natural inversion of 'alias_method_chain' implemention. This method would probably never fly with the core team, so it is merely a re-implementation/repurposing rather than an attempt to DRY the aliasing code.


As an example of what I'm talking about, imagine that you have this chain..

class User
def cry
puts "cry"
end
end

User.new.cry
User.class_eval do
def cry_with_emotion
puts "WAH WAH WAH"

cry_without_emotion
end

alias_method_chain :cry, :emotion
end

User.new.cry



Let us say that you want to alter the emotive nature of that extension in the same ruby session

User.class_eval do
def cry_with_emotion # slightly less emotive
puts "Wah Wah Wah"

cry_without_emotion
end
end

User.new.cry

User.class_eval do
define_method :cry_with_emotion do
puts "Wah Wah Wah"
end
end
User.new.cry # no luck again eh??


As you can see, redefining an interstitial method does not automatically make it part of the chain! Try this on for size (after redefining your method).


User.class_eval do
alias_method_chain_unlink :cry, :emotion

alias_method_chain :cry, :emotion
end
User.new.cry


That works! If you can imagine it, this hack can serve to either allow you to remove something out of a long alias_method_chain, or, allow redefinition of chain link (for lack of a better term)! I might have more to say about metaprogramming in Ruby later, but for now, may this approach save someone as much time as it saved me!

Tuesday, October 27, 2009

Guitars and Harmony


Last night, I recorded a short little Bach choral thing on guitars (over 100 of my friends/colleagues sang it together today!). It sort of reminded of why I love music and guitars so much. Harmony!



[audio:ChoralVerse.mp3]



I could probably spend all day pointing out the passages and moments of harmonic bliss that made me want to be a guitar player, but, suffice it to say that those moments of two-or-more simultaneous guitars bolstering a melody are what I live for.



You'll quickly discover that recording guitars and stacking them is as big an artform as shredding or doing mind-numbing cadenzas at light speed. Its hard stuff to get it to sound right. Here are a few scenarios.



Classical Arrangements



One thing that really sucks about trying to do arrangements of harmonically rich classical tunes with electric guitars is the lack of voice separation and clarity when you use a distorted electric guitar. The blending of voices with guitars when you have 3 or 4 simultaneously sounds absolutely badass (just check out the immense harmonies in Passion & Warfare, Steve Vai's crowning guitar achievement). They do NOT, however, have the same sound as a string quartet, or a choir. With those instruments you can hear the subtle interplay between various voices.



Required listening for this sort of style must include all of Paul Gilbert's dalliances with guitar arrangements on his solo album. The Gilberto Concerto and Whole Lotta Sonata are particularly impressive.



Anyway, what I have learned about getting a good sound goes something like this...



  • Use the tube-iest tone you can find

  • Keep the gain low. A good blendable tone actually sounds like ass by itself

  • Don't use any modulation or ambience effects. The summing of tracks with all that stuff will also sound ass-like

  • Keep the ornamentation to a minimum. You don't want to have 4-5 guitars all doing their own non-harmonious and inconsistent vibrato, slides, or whatever.

  • Don't lose sight of the overall tune. Even if you are just laying track after track, remember to be your own conductor and to keep the flow of the tracks musical.



Here is an example from one of the songs on my eventual solo album. Its a classical-like intro that demonstrates the tones and techniques for blending several guitar tracks nicely into something that allows the simple counterpoint to shine through.



[audio:bootyjonesintro.mp3]



Rock/Metal Harmony Guitars



This is a little more complicated, in my opinion. There are so many variations in sound that you can get.



For a Maiden/Priest type of guitar sound, you don't need perfection. As a matter of fact, inconsistencies in ornamentation and tone between the voices gives it that organic sound which we all know and love. Also, its rather simple, in that, the harmonies are almost always diatonic thirds or some diatonic fixed interval. Play the melody, then record a melody a third up in the same scale. Easy as sin!



Vai-like harmonies (and Satriani on occasion) are of a different sort. You need a moderate amount of gain, no modulation, and you want all of the voices to be consistent (so that they form a nice wall of sound, with no gaps or audible breaks/impurities). Also, they are barely ever as simple as just a constant diatonic interval. Here are some examples of different harmonizations.



Vai: Liberty (1:12 into it). The melody is harmonized like a chord-melody. The harmonies underneath are actually spelling out the progression. When the VII chord comes in at 1:18, the harmonies just nail it. There is no simple formula for that, except for composing it using some of the strictness of 4-part writing but the looseness of Rock-and-Roll and just giving it vibe/attitude when required.



Vai: I Would Love To (2:36). This run is just harmonized in diatonic 4ths. The whole idea behind avoiding parallel 5ths in traditional part-writing is that they effectively sound as if a voice has disappeared. When you only have singers, a sudden parallel fifth just leaves a weird gap. Parallel 4ths do not have that problem (try recording examples for yourself to hear the difference). When Vai does these fatass runs, he sort of just knows to use parallel 4ths to achieve that unholy badass sound. I mean, that run is the SHIT!



In the same song, at around 3 minutes, he rides out that melody to the end. You'll notice really subtle harmony layers underneath it. This is a mix of chord-melody and parallel pentatonic harmonies. When doing your own melodies, imagine doing pure pentantonic harmonies. Then, when laying that over a chord progression, move only a few notes that really accentuate the chords into place. Most of those harmony notes are just passing tones anyway. They don't need to all accent the chords! This leads to...



Joe Satriani: Lords of Karma (3:40)



He plays this beautiful melody for a while, then brings in that harmony line. I can't describe what effect that harmony line had on me when I heard it as a 10 year old. It just messed me up in the coolest way.



A fun exercise for really understanding pentatonic harmonies is to just take some melody line, and harmonies it the same way that you do with diatonic thirds, except always move along the pentatonic scale instead of the full 7-note diatonic scale.



I'll most likely do a thorough breakdown of all things guitar-related from the upcoming Mindwarp Chamber album. Its not terribly dense, as, Scott's vocals really need space to shine through and I'm perfectly happy to not try and innovate every few seconds. Most of the solos are full of insane little harmonies and melody experiments.

Tuesday, June 9, 2009

View Path Manipulation for Rails with AOP

If you have ever had to support multiple subdomains in Rails, you've probably had the same questions that we all have.

  • Where do we place the switching mechanism and how does it work?

  • Does it affect controllers, or just views?

  • How do helpers factor into it our strategy?


There are tons of examples out there on the net. I've chosen (like many others) to do basic view path manipulation based on some sort of runtime switching. With Rails 2.3, however, the view-caching that happens when you set view_paths with the typical view_path methods (prepend_view_path, view_path=, etc...) is crazy expensive and a bit mysterious (unless you frequently hack around in the framework, but the majority of us don't). The guys at Unspace seem to have arrived at a great solution for their switching needs. I did it a bit differently!

The Problem

ActionController::Base.view_paths looks like an array of file paths. It is NOT an array of file paths! It is a subclass of Array known as ActionView::PathSet containing instances of ActionView::Template::Path. The following examples, for this reason, are prohibitively nonperformant under heavy load with deep view hierarchies.
ActionController::Base.view_paths = ["app/views", "app/views/my_app", "app/views/your_app"]
or
ActionController::Base.prepend_view_path "app/views/my_app"

If you dynamically set the view paths with a bunch of strings, they will be typecast into ActionView::Template::Path objects which cache everything in the view path recursively... on EVERY REQUEST. Totally expensive!

The first obvious optimization (assuming you already have things wired up and are just trying to optimize the view path loading) would be to pre-process those String filepaths and store them so that view_path manipulation doesn't incur that insane expense during a request.

My issue with this approach is that the internals of PathSet caching and its typecasting become implemented in runtime request code. The class definitions of the controllers is the last place that I'd put framework hackery of that complexity. In most of my applications, I have a pretty good division between bootstrap/runtime extensions to the framework and actual run-on-every-request application initialization code. I'd just monkey patch those path classes directly, and set the view paths once at bootstrap time.

My needs for switching in an application are basically...

  1. app/views would be your fallback path, application view paths would be mutually exclusive

  2. application views would be of the form...
    views, views/app1, views/app2, ..., views/appN-1, views/appN

  3. Prioritization of a single app would lead to a view path set of the form...
    views/appX, views, views/app1, .... views/appX-1,views/appX+1,.... views/appN

  4. a per-request based switching mechanism (completely ignoring per-Controller view_paths)


A Solution
# Place these in a bootstrap-only file, like a config/initializers script.
ActionController::Base.class_eval
# Assumes a per-application/request view prioritization, not per-controller
cattr_accessor :application_view_path
self.view_paths = %w(app/views
app/views/application_one
app/views/application_two).map do |path| Rails.root.join(path).to_s end
end

ActionView::PathSet.class_eval do
def each_with_application_view_path(&block)
application_view_path = ActionController::Base.application_view_path

if application_view_path
# remove and prepend the view path in question to the array BEFORE proceeding with the 'each' operation
(select do |item|
item.to_s == application_view_path
end + reject do |item|
item.to_s == application_view_path
end).each(&block)
else
each_without_application_view_path(&block)
end
end

# as usual, lets play nice with anything else in the call chain.
alias_method_chain :each, :application_view_path
end

# Place this in application_controller
class ApplicationController < ActionController::Base
before_filter :set_application_view_path

def set_application_view_path
ActionController::Base.application_view_path = request.subdomains.first # IF you happen to use subdomains to switch (i.e. store.app.com, inventory.app.com)
end
end

To understand this completely, you MUST look at PathSet#find_template and understand how it works. After that, try imagining the cheapest way to influence the search order of the view paths. This method is one of those classic Rails-internals methods that does WAY too much in a single method. The only way to hack it is to override it completely or metaprogram a sneaky hack like this. I prefer the sneaky hack because influencing the iteration of the PathSet object introduces FAR less complexity than overriding or having a set of filters to constantly manage this stuff from the controllers.

Now, I have a personal rule to NEVER be immediately satisfied with with my first solution to a complex problem. Unlike music, where a first take for a guitar solo is usually imbued with an irreproducible spontaneity, my sweet spot for software is usually the second or third immediate refactoring!

I've been hearing about AOP from Ken Pelletier, my highly esteemed colleage (a dude that smiles fondly when he hears mention of Smalltalk) for years now. A sudden idea for a refactoring of this code gave me all impetus that I needed to dig into AOP and Rails. I wanted to see if using the AOP methodology would cleanup the pseudo-AOP-through-Ruby-metaprogramming junk that I typically code. Here's the quick refactoring with Aquarium (AOP for Ruby).

A Better Solution
# Put all of this in a bootstrap-only initializer
ActionController::Base.class_eval do
APP_ONE_VIEW_PATH = "app/views/application_one"
APP_TWO_VIEW_PATH = "app/views/application_two"

cattr_accessor :application_view_path
self.view_paths = ["app/views", APP_ONE_VIEW_PATH, APP_TWO_VIEW_PATH]

# This is where you determine the switching mechanism for your application. Here, it is a simple GET parameter.
# You can probably argue that this specific piece SHOULD be in your actual app_controller class definition, as it is the only piece
# of info pertinent to the rest of your application.
before_filter do |controller|
ActionController::Base.application_view_path = controller.params[:application_two] ? APP_TWO_VIEW_PATH : APP_ONE_VIEW_PATH
end
end

require 'aquarium'
ActionView::PathSet.class_eval do
include Aquarium::DSL
before :find_template do |join_point, object, *args|
object.each_with_index do |path,i|
object.unshift(object.delete_at(i)) if path.to_s == ActionController::Base.application_view_path
end
end
end
# I'll leave the exercise of testing this or implementing it for your particular app up to you.

As you can see, AOP allows the operation to be expressed very cleanly and succinctly. I love the feeling of swiping in some functionality horizontally through the framework code, in a way that doesn't rely on too much internal knowledge of its workings.  AOP seems really powerful but it will probably require quite a bit of discipline to use it properly on a very large Rails system in a performant way. Hopefully more resources on AOP best-practices emerge soon (I mean specifically for Ruby, we are sort of handicapped by the performance hit of using this wonderful framework).

I should apologize for moving through this stuff without as much explanation as it deserves. AOP is pretty badass. I'm going to be digesting all of the literature on this topic for a while! Next time, I'll blog about something Music-related. I think that you'll start seeing the parallels in Music Composition and Software Engineering pretty clearly. On that topic, Jonathan Dahl gave a pretty good presentation on the parallels between music and software at RailsConf this year. It was a great presentation, and everything he had to say was right on the money. For the first time, however, I got the feeling that it was a topic upon which I could expound prolifically. I'm going to try and formulate some interesting content along those lines!

Saturday, May 30, 2009

My New Sony Reader

I'm not one for saving the earth, countering the greenhouse effect, eating organic, or reducing my carbon-footprint. If anything, I'm all about increasing my physical footprint by consuming the dirtiest cow-meat that I can find, dripping in A1 and genetically modified vegetables that have no reason to exist at this time of year. Alas, the one thing that I can't compromise in the goal towards the betterment of society is my food.

So, it was with a great sense of hypocrisy that I purchased a Sony eBook Reader this weekend under the guise of saving paper and potentially preventing the inevitable felling of the rainforests. I can safely say, that it was worth it. I love this thing.

Here is why I believe you should get one (assuming that you find your personality or thinking to be inline with mine). Also, don't mind the intertwined arguments between Sony vs. Amazon and just physical books vs. eBooks.

  1. Easy File Management: Kindle has wifi/3g. I don't care, I plug my Sony in to charge via USB anyway, so the wifi doesn't help me. Also, I wouldn't use Sony or Amazon's file management, regardless. Download Calibre, the open source book reader utility, and save yourself a feces-load of trouble.

  2. Less To Move: Everytime I move to a new home, the part which chews the most rotten cud, would be moving my books. I have about 3 big boxes worth of books that I absolutely cannot bare to part with. I pull a back muscle EVERYTIME that I try moving them. Enough of that. When I relocate next, it'll be with my Guitars, Amps, Quiver of Arrows, Sac of Potions, Laptop, and my Sony Reader 505!!

  3. Big Screen: For the most part, this thing is comparable to a paperback novel in text size. I happily read books on my iPhone with Kindle for the iPhone™ and Stanza, so this is an upgrade for me. I won't expound upon the virtues of E-Ink here, as its been touted widely elsewhere. Suffice it to say, that it rocks, looks great, and doesn't hurt your eyes after extended reading periods.

  4. Looks: Sony's Reader looks awesome. The Kindle looks like my retarded cousin drew it (you know which cousin you are... yes you). It looks like something I'd have designed in pre-school. It is Manatee-white. The keyboard is a mar upon the face of an already dismal interface. Sony's has that matte Metal finish with Chrome accents.  It is so damn hip, that I feel uglier when using it.

  5. Expandability: I, like most geeks, despise Sony Memory Cards. The world absolutely did NOT need an yet-another-flash-based-storage device. We already had a cluster-fornication of choices with MMC, SDHC, and Smart Media/Cards.  (A quick aside... Does anyone HATE those computers with a giant portion of the front-panel devoted to various memory-card formats? Seriously, appealing to the lowest common denominator seems ok, but is any one person going to be using all of those slots?). Expandability format aside, the Sony is expandable. The Kindle is not. That makes the Sony a winner in my book. ~200MB is paltry. Paltry, I say. Roger Paltry.

  6. Wrist Pain Alleviance: Maybe most people know how to read books. I hold books with a very odd looking claw shaped hand formation. I do not believe there is anything ergonomic about a pile of cellulose sheets glued together. The Reader feels as if its a natural extension of myself that I have been holding for my entire life. Dudes, you know what I'm sayin'.


There are two cons AFAIK...

  1. Scent: You don't get that 'book smell'. That delicious fibrous scent that persists from the first opening crack of a book to the final triumphant climactic phrase that typically makes you cry or smile. All you get with these readers (Kindle or the SR), is the cold metallic touch of a machine that serves your book from a silent array of bits. The very machine that probably plots the overthrow of all that you love and hold dear. The Sony Reader definitely looks like something that would join its SkyNet brethren in the conflict to remove the ability to read from all humans by terminating them.

  2. Necronomicon: The beauty of the Necronominican reading experience is the fact that it is written in blood and bound in human flesh. You don't get those sort of experiences when reading ancient tomes on a book reader. The same argument applies to pop-up books for the kiddies, and bibles that are meant to contain Tommy Guns and Jail-Cell keys.


All of the comparisons on the web were laced with stats and numbers. I hate stats and numbers (a marked change from the stats-whore that I used to be). Just remember a few things.

  1. Having an eBook reader is better than not having an eBook reader.

  2. Having the Sony Reader is arguably better than having the current incarnation of the Kindle.

  3. Having an eBook reader and possessing/reading physical books are not mutually exclusive operations.

  4. I have a retarded cousin who can design Kindle-like hardware for you.


My reader came with Pride and Prejudice pre-installed. Which reminds me, the Kindle is not available outside of the US. The Sony Reader included a British book, almost in blatant scoff-age (scoff-itude?) at those Bozos (Bezos?).  For those of you that don't read regularly, GO GET ONE!

Monday, May 25, 2009

Site Relaunch

This weekend, I decided to merge my AHG Software and AxehomeyG projects into one entity. Maintaining a separation between both aspects of my life has caused me nothing but headaches.

Just a quick recap about ME, since this is MY blog, after all...

My name is Mike Cerna. I write music and software programs. I love Physics, Math, Quantum Mechanics, Thermodynamics, Chemistry and most of the natural philosophies (that is such a weird moniker for the sciences, isn't it?).  I'm also a web developer (www.thepoint.com, www.highend3d.com). I don't perceive my interests in the aforementioned to be driven by anything more than basic education and general feelings. Those general feelings are as follows..

Music

I've been playing for a very long time. I won't even bother saying when any more, because there were so many starts and stops from as early as I can remember. Music is about listening as much as performing and there are times when I just listen and analyze for weeks, months, and in the past, years. There is a key indescribable component to music (and the ordered collection of frequencies and timbres of which it is composed) which renders any sort of measurement irrelevant. When I rant about music, it is in such vague terms, and I love it. It is so easy to get lost in conversation about music.

Performance and Composition go hand in hand. As an art, it is akin to speech, in that there are great orators, and crappy orators. There are those that can barely speak their own language, and those that can confound the senses with their words. Orthogonal to that concept is the value of content that is performed or spoken. The same capacity for profound statements exists at all levels, and by all speakers. I've thought about this since childhood, and, most of my musings on the subject are not rooted in science and linguistics so much as observation and vague parallels that I draw when I'm in the depths of a performance or writing session. I'm sure that I'll continue researching the research out there, and blog about this topic in the future. Read More... so that, if ever we meet, you and I, we can discuss the analogy to our heart's content.

Software

In 2001, while pursuing my Music Degree, I decided that my triumph-over-adversity schtick wouldn't be appealing if I lived my upcoming years as a poor musician (I had a memorable, but shitty childhood, which should have led to a life of misery and acquiesance of the perils and punishments of poverty. Instead, I persevered against all odds due to the immense size of my head and enclosed brain. Even though there are smarter people with smaller heads out there, mine saved my ass!). I enrolled in the Computer Science program at Northern Illinois University and carved out my path from there. Immediately,  I realized that software was awesome and a true marvel of human accomplishment. It was truly multidisciplinary. Game development, in particular, was incredibly dense with calculus, numerical computation, and physics. Try writing a Ray-Tracer from scratch and you will understand!

Fast forward to the present. I'm a Rails Developer at ThePoint.com. Groupon.thepoint.com, the commercial arm of the application, is growing HUGE. The idea works! Kudos to Andrew Mason, for grasping and selling social media/marketing and web-powered collective-action in a way that no one has before and Ken Pelletier for making the system come to life through technology (Damn, that was a mouthful, why does everything web-related have to be this syllabic monstrosity).

My knowledge of physical sciences is about an order of magnitude more developed than my awareness and familiarity with problems plaguing society, our economy, and the world at large. Doing my part to develop something that allows people and businesses to fix their own problems is really the perfect task for me.

Anyway , one thing that I've noticed in all of my time developing software, is that everyone loses sight of the big picture at some point (myself, wholeheartedly included). There is ALWAYS a business goal that sits outside of your current task. There is ALWAYS complexity in any solution or system, which is waiting to sprawl and grow. The Laws of Thermodynamics (specifically the second, which I love to use to explain a point about natural decay) doesn't actually apply to thoughts and organizational systems (unless you count neural decay and bit-rot). I'll argue that its principles can still be unscientifically applied to thoughts, development strategies, and code. Our solar-powered ordering of all things earthly allows us to temporarily reverse the tide of this entropic tangle. People need to be aware that elegance, beauty, perfection, systemic-integrity (like ensuring some dogmatic principle is adhered to within the full-stack of a software application) are all pointless if they lower the value of your software due unmaintainability or just make the entire operation needlessly complex. ANY stakeholder, developer, or employee can make an assessment about an operation being more complex than it needs to be to perform a function. Being aware of all of this, in concrete terms, is a difficult task for any programmer. There are those of us, who want more than nibbles of wisdom from our daily lives and excerpts from the Pragmatic Programmers books, but less than a full analysis of current paradigms and complexity-managing processes. I want to discover these things. Blogging about what I find sounds like fun and something of value to those of like mind. I can probably rant about binding entropy in life, music, software, and just about anything, ad-inifinitum, so I'll just leave it at that.

I believe that my current job, and my current band, both represent a wonderful reversal of entropy. I have turned countless McD's cheeseburgers into some great music, and some great code.  Over the following months, time-permitting, I'll talk about the nitty-gritty of my findings in an interleaved fashion.  For now, check out my blog-links for links to my band, Mindwarp Chamber, my music, or my sites and applications!