I needed a simple filmstrip plugin for the when I was building a page for honk.com (see the "Honk Users also look at" section). I browsed several plugins, and tried two: GalleryView, and Scrollable, and ended up using Scrollable.
I had no need for a gallery, mouse-over animations, or timed slideshow options, but most of the tools I found that included filmstrip capability also included many or all of these extraneous features which I would have to disable to get my desired result. What I did need was built in next/previous behavior (but not assets!) and the ability to style the slideshow elements and link them to an external page, rather than a gallery display.
My first attempt used GalleryView, which is not really the best fit for the requirements listed above. While I suspect this is a lovely gallery tool if what you actually want is a photo gallery, I ended up sifting through lots and lots of unnecessary (for my purposes) code in order to strip away the features I didn't need, and while I was left with a working filmstrip, I couldn't style the buttons or filmstrip elements without breaking the functionality of the filmstrip. On top of these woes, I couldn't use anything but 22px x 22px images for the browse buttons. So I scrapped my GalleryView attempt and started over with Scrollable at the suggestion of a coworker.
Scrollable takes the opposite approach: it starts with a simple filmstrip and you add more plugins if you want more functionality. It was perfect for my purposes because it consisted of relatively little code, and allowed me to make the scrollable items whatever kind of element I want, with fast setup and clear documentation. I could tell with very little time commitment that it was going to allow me to build what I needed. The browse buttons could be any size or kind of element I wanted - they are just tagged with a class. The one inflexible requirement is that you must structure your items in divs containing preset numbers of filmstrip elements. I can't say much about the functionality of Scrollable's gallery setup, animation, or other options, because I didn't need them, and so didn't have to touch them, which is the way it should be!
Friday, May 14, 2010
Friday, April 30, 2010
Jelly for Unobtrusive Javascript
There seems to be a lot more talk about unobtrusive javascript than actual practice. This is probably due to the fact that despite the benefits of unobtrusive javascript, it can be a hassle to adhere to the standards of unobtrusiveness. It's so easy to just inline some code when you need it, sticking it right in your html, rather than use a hook and assign your script to a DOM element. However, if you do it the quick dirty way, it's both hard to test your javascript, and hard to mix up or swap out visual elements without touching (and possibly breaking) the behavior of your inline javascript. But don't fret, there are tools out there to help you keep your html clean, and your javascript testable.
At Honk, we use Pivotal's jelly by Brian Takita to integrate javascript into our rails app. Jelly gives you the tools you need to attach scripts, watch for on-page events, and handle callbacks. With jelly, you keep your javascript in seperate .js files, and attach it using the method attach_javascript_component("SomeJS", *params), which will call the init function of your component using the params passed in. This is just the start - there are more methods for setting up observers and triggering responses. You can read in detail about jelly here.
At Honk, we use Pivotal's jelly by Brian Takita to integrate javascript into our rails app. Jelly gives you the tools you need to attach scripts, watch for on-page events, and handle callbacks. With jelly, you keep your javascript in seperate .js files, and attach it using the method attach_javascript_component("SomeJS", *params), which will call the init function of your component using the params passed in. This is just the start - there are more methods for setting up observers and triggering responses. You can read in detail about jelly here.
Thursday, April 22, 2010
More Sass.
Variables, Part II:
Let me share with you some things that might be obvious, but I'll point them out just in case you are unnecessarily constraining yourself:
Optional assignment is supported in Sass. So go ahead and |= your heart out.
Also, Default arguments are supported for your Sass mixins. Just provide a default value the same way you would for ruby methods.
This one might be less obvious: You can use ruby-style string interpolation on variables, even in the middle of selectors or properties. I was pleasantly surprised to discover that it is totally acceptable to do something like
Which essentially amounts to "make blue_text blue." The ability to interpolate variables makes it easy to write template methods that construct CSS given just the few variables you care about changing.
Comments:
There are two kinds of comments in Sass. If you want your comment to show up in the CSS compiled document in addition to your Sass file, use /*, as in:
Or, if you want the comment to show up in your Sass file, but not in the CSS document, use //, as in:
I find I use the quieter version of the comment almost exclusively, but what you use will probably depend on whether other developers will be looking at your Sass, or at the CSS it produces.
Let me share with you some things that might be obvious, but I'll point them out just in case you are unnecessarily constraining yourself:
Optional assignment is supported in Sass. So go ahead and |= your heart out.
Also, Default arguments are supported for your Sass mixins. Just provide a default value the same way you would for ruby methods.
This one might be less obvious: You can use ruby-style string interpolation on variables, even in the middle of selectors or properties. I was pleasantly surprised to discover that it is totally acceptable to do something like
p.#{!color_of_my_words}_text
color: !color_of_my_words
Which essentially amounts to "make blue_text blue." The ability to interpolate variables makes it easy to write template methods that construct CSS given just the few variables you care about changing.
Comments:
There are two kinds of comments in Sass. If you want your comment to show up in the CSS compiled document in addition to your Sass file, use /*, as in:
/* Hey, I'm totally all up in your CSS.
Or, if you want the comment to show up in your Sass file, but not in the CSS document, use //, as in:
// Ssh, y'all can't see me except for right in this here Sass.
I find I use the quieter version of the comment almost exclusively, but what you use will probably depend on whether other developers will be looking at your Sass, or at the CSS it produces.
Sunday, April 18, 2010
Sass.
If you work with CSS, you owe it to yourself to check out SASS, or Syntactically Awesome Style Sheets. That's right, the A is for awesome. Here's why:
It's pretty. Sass drops all the curly brackets and semi-colons, and just uses white space to figure out which property-value declarations go with which selectors. This makes for a very clean looking syntax. But it's hardly the only reason Sass is neat.
It's DRY. As in Don't Repeat Yourself. For one, selectors may be nested within one another, avoiding the need to repeat selectors for more specific cases. If you want to refer to an li with a "my_list" class within a div, it's as simple as this:
Just throw in any other declarations below the selector you want them to apply to, and at the proper indentation. In RubyMine, groups of selectors are even collapsible, so you can keep irrelevant ones out of view.
For two, it lets you use variables, which look like "!variable". This means you don't have to go around changing common values in multiple places, but it gets better - you can perform arithmetic operations on variables. You can set up the width of a div to be automatically adjusted if you change your margin variables, for example. This is really handy for value tweaking when you're fine tuning your styling.
Mixins. Are neat. Define a mixin with "=my_mixin" and use it with "+my_mixin". Use it all over the place. You can use it way more than once, but you secretly only have to write it once (shhh.) But it gets awesomer. Mixins can take variables, as in "=my_mixin(!var)". You can use mixins across multiple pages that share similarly styled elements, saving yourself a lot of work.
Get Sassed. I swear you won't regret it.
It's pretty. Sass drops all the curly brackets and semi-colons, and just uses white space to figure out which property-value declarations go with which selectors. This makes for a very clean looking syntax. But it's hardly the only reason Sass is neat.
It's DRY. As in Don't Repeat Yourself. For one, selectors may be nested within one another, avoiding the need to repeat selectors for more specific cases. If you want to refer to an li with a "my_list" class within a div, it's as simple as this:
body
background-color: white
div
display: block
li.my_list
margin-left: 10px
Just throw in any other declarations below the selector you want them to apply to, and at the proper indentation. In RubyMine, groups of selectors are even collapsible, so you can keep irrelevant ones out of view.
For two, it lets you use variables, which look like "!variable". This means you don't have to go around changing common values in multiple places, but it gets better - you can perform arithmetic operations on variables. You can set up the width of a div to be automatically adjusted if you change your margin variables, for example. This is really handy for value tweaking when you're fine tuning your styling.
Mixins. Are neat. Define a mixin with "=my_mixin" and use it with "+my_mixin". Use it all over the place. You can use it way more than once, but you secretly only have to write it once (shhh.) But it gets awesomer. Mixins can take variables, as in "=my_mixin(!var)". You can use mixins across multiple pages that share similarly styled elements, saving yourself a lot of work.
Get Sassed. I swear you won't regret it.
Monday, April 12, 2010
ActiveRecord and MySQL
The way we interact with data from the rails side of things is conveniently object-oriented. Groups of objects are stored in tables, along with information about how they are connected to other objects. A table contains all instances of a given class as rows (one row per object), and is always pluralized. So we might have a table containing all of our ArchEnemy objects, called arch_enemies. (By the way, there is a touch of rails magic happening here - rails knows that “people” is the plural of “person”, for example.)
Without rails, however, the convenience of object-orientation is not built in to the database. Chances are the database is a relational database (like MySQL, Postgres, or SQLite). Without the convenience of rails, data can be accessed using the ruby MySQL module, which has built in methods to establish connections, run queries, and interact with the resulting datasets returned by queries.
If we want to interact with the database without having to write SQL queries, we need a layer of logic to map classes to tables, objects to rows, and attributes to columns, so that we can interact with the database as if it were object-oriented. The layer that handles this is doing object-relational mapping, or ORM. In rails, the built in ORM layer is ActiveRecord. Using ActiveRecord you can easily find information using methods like first, find, and find_all, and change information in the database using save, or update_attribute (which I use often for test purposes to directly change an attribute while circumventing a save and its associated validations.)
Accessing data through the ActiveRecord layer is fine in many cases, but let’s say you need to add, retrieve, or modify a large amount of data, or maybe you want to use a massive CSV from an outside source, and are only interested in extracting portions of the data. In these cases, the usual methods can be unreasonably slow, and you will probably want to use SQL directly. This can be done using
ActiveRecord's execute method returns a Mysql::Result object, which is a result set. Result sets consists of a set of rows from the database, and a cursor that points to the current row. In order to access data from a row in a result set, that row must be the current row, and the cursor must iterate over all previous rows first. This makes it extremely expensive time-wise to access a particular attribute repeatedly (say inside a loop), and it can be very advantageous to assign data to a local variable if it is going to be needed multiple times during a loop.
Without rails, however, the convenience of object-orientation is not built in to the database. Chances are the database is a relational database (like MySQL, Postgres, or SQLite). Without the convenience of rails, data can be accessed using the ruby MySQL module, which has built in methods to establish connections, run queries, and interact with the resulting datasets returned by queries.
If we want to interact with the database without having to write SQL queries, we need a layer of logic to map classes to tables, objects to rows, and attributes to columns, so that we can interact with the database as if it were object-oriented. The layer that handles this is doing object-relational mapping, or ORM. In rails, the built in ORM layer is ActiveRecord. Using ActiveRecord you can easily find information using methods like first, find, and find_all, and change information in the database using save, or update_attribute (which I use often for test purposes to directly change an attribute while circumventing a save and its associated validations.)
Accessing data through the ActiveRecord layer is fine in many cases, but let’s say you need to add, retrieve, or modify a large amount of data, or maybe you want to use a massive CSV from an outside source, and are only interested in extracting portions of the data. In these cases, the usual methods can be unreasonably slow, and you will probably want to use SQL directly. This can be done using
To safeguard against SQL injection attacks, it’s a good idea to first run your query through sanitize_sql as such:ActiveRecord::Base.execute(some_sql)
ActiveRecord::Base.sanitize_sql(some_sql))
ActiveRecord's execute method returns a Mysql::Result object, which is a result set. Result sets consists of a set of rows from the database, and a cursor that points to the current row. In order to access data from a row in a result set, that row must be the current row, and the cursor must iterate over all previous rows first. This makes it extremely expensive time-wise to access a particular attribute repeatedly (say inside a loop), and it can be very advantageous to assign data to a local variable if it is going to be needed multiple times during a loop.
Friday, April 2, 2010
lambda
Although they aren’t as common as blocks in ruby, I’ve been encountering some lambda usages, and usually find myself proper confused. This is undoubtedly because I have an incomplete understanding of closures, which goes something like this: I think of a closure as a bit of code that has a shorter lifespan than the variables it accesses. I understand blocks to be closures that are defined in the context of a method call, and by comparison, lambdas seem to be closures that are not dependent on a method call, but can rather be simply stated, assigned to a variable, or executed on the spot. You can explicitly pass a lambda as a block to a method like this:
Where my understanding gets especially fuzzy is how lambdas differ from procs - from what I can tell, “lambda” is *nearly* equivalent to “Proc.new”, except that it handles returns differently, as seen in the ruby example on Wikipedia's closure page.
I’d like to see some useful applications of lambda, maybe this would help me "get it." So far, the most common usage of lambda that I’ve seen in the last few weeks is in rspec tests to do something like this:
which conveniently allows you to check that the count of your Customers changed without having to explicitly offload the count, call the method, and then check it again. (The rspec matcher “change” evaluates the provided value before and after the lambda.) For now, I'll keep my eyes out for more lambdas.
my_block = lambda {|x| puts x}
some_method(&my_block)
Where my understanding gets especially fuzzy is how lambdas differ from procs - from what I can tell, “lambda” is *nearly* equivalent to “Proc.new”, except that it handles returns differently, as seen in the ruby example on Wikipedia's closure page.
I’d like to see some useful applications of lambda, maybe this would help me "get it." So far, the most common usage of lambda that I’ve seen in the last few weeks is in rspec tests to do something like this:
it “should create a new customer entry” do
lambda do
make_new_customer(“John Doe”)
end.should change(Customer, :count).by(1)
end
which conveniently allows you to check that the count of your Customers changed without having to explicitly offload the count, call the method, and then check it again. (The rspec matcher “change” evaluates the provided value before and after the lambda.) For now, I'll keep my eyes out for more lambdas.
Friday, March 26, 2010
the magical method_missing
In a typical method call, ruby will send the method name and arguments as a message to the object on which the method is being called. Most of the time, this will be an existing method, but if it is not, ruby calls a method called method_missing. The default behavior of method_missing is to throw a NoMethodError, which is exactly what you will get if you try, for example “i’m a string”.bglarbl.
Now, like any other method, method_missing can be overridden. A common rails use, and how I first discovered method_missing, is to simplify database queries and make them more readable. In rails, courtesy of method_missing, you can find_by_any_arbitrary_attribute without having to explicitly write the method to do so - as long as “any_arbitrary_attribute” is a column in your table, method_missing will take care of the rest.
You can do all sorts of tricky things here, which is both an expressive and dangerous feature (an increasingly recurring theme, I find, the more I learn about ruby.) You can do some really neat, useful things, like implement domain specific languages, but you can also do some really stupid, crazy-making things, like accidentally return “true” every time you call a non-existent, or even just a misspelled, method. Less dangerous, but still mildly annoying, is the fact that overriding method_missing can easily cause an object to respond to a method, while respond_to? will still return false for that method name, and the method will not show up in the array .methods returns. The big idea here is that overriding method_missing makes it really easy to make debugging really hard.
There are some ways to avoid making debugging a pain, however. One is to also override respond_to. Alternatively, depending on the expected usage, you might want to have method_missing dynamically construct a method, which will add the method to the methods list, and cause the expected behavior for respond_to. After some failed attempts at using define_method to do this, here’s one way to do this that works:
Now, you can make a new instance of MethodMissingTest - let's call it "feed_me_methods" and call any random string as a method on feed_me_methods, and feed_me_methods will now actually contain a method by that name, rather than just act like it does.
If you want to play some more with this, Sarah Allen has made a fun test-first xml tag-generator exercise. Cheers, and remember to method_missing responsibly!
Now, like any other method, method_missing can be overridden. A common rails use, and how I first discovered method_missing, is to simplify database queries and make them more readable. In rails, courtesy of method_missing, you can find_by_any_arbitrary_attribute without having to explicitly write the method to do so - as long as “any_arbitrary_attribute” is a column in your table, method_missing will take care of the rest.
You can do all sorts of tricky things here, which is both an expressive and dangerous feature (an increasingly recurring theme, I find, the more I learn about ruby.) You can do some really neat, useful things, like implement domain specific languages, but you can also do some really stupid, crazy-making things, like accidentally return “true” every time you call a non-existent, or even just a misspelled, method. Less dangerous, but still mildly annoying, is the fact that overriding method_missing can easily cause an object to respond to a method, while respond_to? will still return false for that method name, and the method will not show up in the array .methods returns. The big idea here is that overriding method_missing makes it really easy to make debugging really hard.
There are some ways to avoid making debugging a pain, however. One is to also override respond_to. Alternatively, depending on the expected usage, you might want to have method_missing dynamically construct a method, which will add the method to the methods list, and cause the expected behavior for respond_to. After some failed attempts at using define_method to do this, here’s one way to do this that works:
class MethodMissingTest
def method_missing(method_name)
method_source = "
def #{method_name}
puts 'added a method'
end
"
instance_eval(method_source)
send(method_name)
end
end
Now, you can make a new instance of MethodMissingTest - let's call it "feed_me_methods" and call any random string as a method on feed_me_methods, and feed_me_methods will now actually contain a method by that name, rather than just act like it does.
If you want to play some more with this, Sarah Allen has made a fun test-first xml tag-generator exercise. Cheers, and remember to method_missing responsibly!
Monday, March 22, 2010
infinite recursion
If you shovel an array into itself, it causes an infinite recursion. Watch me get dizzy in irb:
by the set of all sets, ain't that cool.
>> whoa = ["one", "two", "three"]
=> ["one", "two", "three"]
>> whoa << whoa
=> ["one", "two", "three", [...]]
>> whoa[3]
=> ["one", "two", "three", [...]]
>> whoa[3][3][3]
=> ["one", "two", "three", [...]]
by the set of all sets, ain't that cool.
RubyMine shortcuts for vim addicts
I'm a long-time vim user, but I've been using RubyMine recently for work. While I'm getting better and better at keeping the force of habit "3yy j p :wq" kind of nonsense out of my code, I still crave the lazyfingered awesomeness. Still, I've found some neat shortcuts in RubyMine that almost make up for my stubborn vim withdrawals.
Find: RubyMine will find instances of a string in the current working file if you hit Ctrl-F, and will do a project-wide search if you hit Ctrl-Shift-F. I was particularly thrilled to discover Ctrl-Alt-B, which will search for the implementation of a method call, which is awesome, even if it doesn't work all the time...
Selecting: holding down control and hitting "." will select blocks of code, and subsequently hitting "." will work its way up the nesting tree selecting parents of parents. This is especially useful in Rspec, for selecting all contexts within a describe, or all examples in a context.
Yank/Put: If you select multiple lines (using shift + arrows, or home/end) you can then move those lines up and down through your code in a block by holding control+shift and using up and down arrows. If you're lucky, and RubyMine is smart enough, sometimes this will actually skip over whole blocks of code that are indented.
Collapse and Search: speaking of Rspec, it can also be handy to collapse an entire spec by hitting Ctrl + Shift + "-", and then find instances of a keyword, which will expand only the instances of that word as they are found, leaving irrelevant tests collapsed.
Running Tests: with your test open, you can press Ctrl-Shift-F11 to run all tests in a spec file. Or, pressing Alt-Shift-F11 will run only the current example (according to cursor location). If the Run window is open, Ctrl-4 will move your cursor to the Run window, and Ctrl-F5 will repeat the last test run.
Commenting out code: pressing Ctrl and "/" will comment out any currently selected lines, and will use the appropriate commenting convention according to the file extension.
Find: RubyMine will find instances of a string in the current working file if you hit Ctrl-F, and will do a project-wide search if you hit Ctrl-Shift-F. I was particularly thrilled to discover Ctrl-Alt-B, which will search for the implementation of a method call, which is awesome, even if it doesn't work all the time...
Selecting: holding down control and hitting "." will select blocks of code, and subsequently hitting "." will work its way up the nesting tree selecting parents of parents. This is especially useful in Rspec, for selecting all contexts within a describe, or all examples in a context.
Yank/Put: If you select multiple lines (using shift + arrows, or home/end) you can then move those lines up and down through your code in a block by holding control+shift and using up and down arrows. If you're lucky, and RubyMine is smart enough, sometimes this will actually skip over whole blocks of code that are indented.
Collapse and Search: speaking of Rspec, it can also be handy to collapse an entire spec by hitting Ctrl + Shift + "-", and then find instances of a keyword, which will expand only the instances of that word as they are found, leaving irrelevant tests collapsed.
Running Tests: with your test open, you can press Ctrl-Shift-F11 to run all tests in a spec file. Or, pressing Alt-Shift-F11 will run only the current example (according to cursor location). If the Run window is open, Ctrl-4 will move your cursor to the Run window, and Ctrl-F5 will repeat the last test run.
Commenting out code: pressing Ctrl and "/" will comment out any currently selected lines, and will use the appropriate commenting convention according to the file extension.
Tuesday, March 16, 2010
block parameter scope weirdness
If the fact that external variables can be changed inside a block isn't strange enough for you, check out this example. What would you presume happens to "index" during the method call?
It is a little alarming, but index is now equal to "goofball." This could make for some very unexpected and undesired behavior if you are not careful about what you are naming your block parameters. Dangerous!
index = "watch this space"
my_array = ["base", "basket", "tennis", "goof"]
my_array.map {|index| index += "ball"}
It is a little alarming, but index is now equal to "goofball." This could make for some very unexpected and undesired behavior if you are not careful about what you are naming your block parameters. Dangerous!
Monday, March 8, 2010
ruby blocks
My first encounter with blocks in Ruby was in a koan, which was a black box kind of experience. I got stuck thinking of the block and the receiving function as two scopes, and under this assumption it seems that a block can return to a method *and* vice versa.
As it turns out, the block convention acts more like a run time code splicer, putting the block of code (before evaluating it) IN the method so, really, there is a shared scope between the two. It’s like you’re slipping the method a little note for what to put in the yield spot. But you can also pass the block a variable from inside the method, by writing yield(variable). It looks something like this:
if you prefer a multiple-line version, you can replace the brackets with do/end (and I'll also throw in an extra surprise):
If you are accustomed to C-like languages, as I am, it can be surprising that our variable_outside_method is actually changed to "foobar" once the method call is resolved. This is because blocks have access to the context in which they are called.
Blocks are extremely expressive and useful for implementing a skeleton form of a task - in fact, enumerators in ruby (e.g. "each", "detect", "select") are implemented using blocks!
As it turns out, the block convention acts more like a run time code splicer, putting the block of code (before evaluating it) IN the method so, really, there is a shared scope between the two. It’s like you’re slipping the method a little note for what to put in the yield spot. But you can also pass the block a variable from inside the method, by writing yield(variable). It looks something like this:
def method_with_a_block
yield(parameter)
end
method_with_a_block {|parameter| parameter.do_stuff}
if you prefer a multiple-line version, you can replace the brackets with do/end (and I'll also throw in an extra surprise):
variable_outside_method = "foo"
method_with_a_block do |parameter_passed_to_block|
do_stuff_with(parameter_passed_to_block)
variable_outside_method += "bar
end
If you are accustomed to C-like languages, as I am, it can be surprising that our variable_outside_method is actually changed to "foobar" once the method call is resolved. This is because blocks have access to the context in which they are called.
Blocks are extremely expressive and useful for implementing a skeleton form of a task - in fact, enumerators in ruby (e.g. "each", "detect", "select") are implemented using blocks!
Thursday, March 4, 2010
ruby on rails
I'm learning Ruby on Rails. I've been spending this week with Sarah Allen, and have done a lot of work on my own from home. For ruby, I've been working the ruby koans from edgecase at github, and reading the ruby documentation and why's poignant guide to Ruby. I've also taken a fresh look at CSS, and have found the css tutorials at w3schools to be a huge help. For Rails, I've been using the Rails guides and Rails documentation for reference. That's it for now, much more to follow regarding the details of what I'm learning!
Subscribe to:
Posts (Atom)