Skip to content

Instantly share code, notes, and snippets.

View practicingruby's full-sized avatar

Gregory Brown practicingruby

View GitHub Profile
name weekday start finish
Gregory Monday 8:30 AM 4:30 PM
Gregory Tuesday 8:30 AM 4:30 PM
Gregory Thursday 8:30 AM 12:00 PM
Hunter Wednesday 10:00 AM 2:00 PM
Hunter Thursday 10:00 AM 2:00 PM
Hunter Friday 10:00 AM 4:00 PM

Inheritance is a key concept in most object-oriented languages, but applying it skillfully can be challenging in practice. Back in 1989, M. Sakkinen wrote a paper called Disciplined inheritance that addresses these problems and offers some useful criteria for working around them. Despite being more than two decades old, this paper is extremely relevant to the modern Ruby programmer.

Sakkinen's central point seems to be that most traditional uses of inheritance lead to poor encapsulation, bloated object contracts, and accidental namespace collisions. He provides two patterns for disciplined inheritance and suggests that by normalizing the way that we model things, we can apply these two patterns to a very wide range of scenarios. He goes on to show that code that conforms to these design rules can easily be modeled as ordinary object composition, exposing a solid alternative to tradi

When Mike Burns outlined his vision of Unobtrusive Ruby, I initially thought it was going to be a hit with the community. However, a lack of specific examples led to a critical backlash and caused the post to generate more heat than light. This is unfortunate, because the ideas he outlined are quite valuable and shouldn't be overlooked.

In this article, I share my own interpretation of what Unobtrusive Ruby means, based on the the points that Mike outlined. I can't guarantee that my take on this is what Mike had in mind, but it should be interesting to those who wanted a better-defined roadmap than what he provided. To get this most out of this article, I recommend going back and reading what Mike wrote before continuing. Try to think about what these concepts mean to you, and then compare them to what I've outlined here.

The following guidelines are the ones Mike laid out, but

require "open-uri"
Prawn::Document.generate("remote_images.pdf") do
image open("http://prawn.majesticseacreature.com/media/prawn_logo.png")
end

Immutable Rules

101: All players must always abide by all the rules then in effect, in the form in which they are then in effect. The rules in the Initial Set are in effect whenever a game begins. The Initial Set consists of Rules 101-116 (immutable) and 201-213 (mutable).

102: Initially rules in the 100's are immutable and rules in the 200's are mutable. Rules subsequently enacted or transmuted (that is, changed from immutable to mutable or vice versa) may be immutable or mutable regardless of their numbers, and rules in the Initial Set may be transmuted regardless of their numbers.

103: A rule-change is any of the following: (1) the enactment, repeal, or amendment of a mutable rule; (2) the enactment, repeal, or amendment of an amendment of a mutable rule; or (3) the transmutation of an immutable rule into a mutable rule or vice versa.

I appreciate all form of contribution, but for some contributors a greater sense of awareness about how OSS works would go a long way. The more you leave undone in a pull request or the more you leave unanswered in a bug report, the more “work in progress” your contribution adds to a project.

So for example, say you report a bug, but you only explain it with a sentence or two of english -- no stack trace, no minimal example reproducing the problem, and no tests. At that point, there’s nothing I can do except ask you to provide more information to help me investigate further, unless your problem is very obvious the moment I look at it.

Once we at least have the means to reproduce a bug, we need to make sure it’s isolated and not coming from some lower level problem. That means writing further sets of examples, and poking around in the source until we’re fairly sure where the bug is coming from.

Once that source of the problem has been identified, we need to work on a fix, but we need to take care to make

- - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - -
- - - - - X X X X X X X X X X X X - - - - - - -
- - - X X - - - - - - - - - - - - X X - - - - -
- - - X - - - - - - - - - - - - - - - X - - - -
- - - X - - - X X X - - - X X X - - - - X - - -
- - X X - - - - - X X - X X - - - - - - - X - -
- - X - - - - - X X X - X X - - - - - - - X - -
- - X - - - - - X X X - - X - - - - - - - X - -
- - X X - - - - - - X X - X X - - - - - X - - -
-module(chopstick).
-export([start/1, loop/2]).
start(Number) ->
spawn(chopstick, loop, [Number, nobody]).
loop(Number, Owner) ->
receive
{take, Owner} -> loop(Number, Owner);
{take, NewOwner} when Owner =:= nobody ->
-module(bowling).
-export([score/1, test/0]).
test() ->
9 = score([{7, 2}]),
% 4 6 8 9 5 0 3 1 0 4
40 = score([{1,3},{2,4},{3,5},{5,4},{2,3},{0,0},{1,2},{1,0},{0,0},{1,3}]),
% 4 6 8 12 5 0 3 1 0 4
my_time_func(F) ->
{MegaS@T1, S@T1, MicroS@T1 } = erlang:now(),
F(),
{MegaS@T2, S@T2, MicroS@T2 } = erlang:now(),
(MegaS@T2 - MegaS@T1)*1000000 + (S@T2 - S@T1) + (MicroS@T2 - MicroS@T1)/1000000.