• App Camp for Girls and an interview at AppStories

    I’ve been following the App Camp for Girls project since it started not a long time ago. App Camp for Girls is a non-profit founded by my friend Jean MacDonald from Smile. Its mission is:

    App Camp For Girls wants to address the gender imbalance among software developers by giving girls the chance to learn how to build apps, to be inspired by women instructors, and to get exposure to software development as a career.

    They’re currently raising funds for the project, so consider donating to this fine endeavor. While it’s already reached its initial funding goal, they’re thinking about expanding the program to additional locations, so any contribution will help.

    To inspire young people to learn application development they started App Stories, where they interview developers about their first steps in software development.

    There are already several interesting interviews available from developers and designers, including an interview with yours truly. More interviews with seasoned developers are going to be published on the site later, so you might want to add it to your RSS feed.

    Have I already asked you to donate? Just a reminder. :)

  • Toggle hosts file for less distractions (in Haskell)

    I decided to edit the /etc/hosts file to block access to some domains that I compulsory visit when working, in order to reduce my distractions. The usual suspects are Twitter, Facebook, Hacker News, and some real-world news sites.

    So I edited the file and added the following lines:

    # -- WORK --
    127.0.0.1     news.ycombinator.com
    127.0.0.1     facebook.com
    127.0.0.1     twitter.com
    

    Now they’re blocked. But I also wanted the option to quickly comment this section out and back again.

    I could do it quickly in Ruby but I thought that it would be a great way to exercise my basic Haskell skills.

    It took me quite a while to get it right — my Haskell is rusty. But after it compiled, I only had one little logical bug, which I quickly found out and fixed.

    The final code is below. It also backs up hosts file (just in case) and prints the resulting hosts file. Both of these steps could be removed, as they’re not important for its main functionality.

    import Data.List
    
    -- Starts toggling the comment after a line that starts with "# --"
    
    processLine switch line
        | length line == 0                          = (switch, line)
        | switch == False && take 4 line == "# --"  = (True, line)
        | switch == True                            = (True, toggleLine line)
        | otherwise                                 = (switch, line)
          where toggleLine l
                  | head l == '#' = tail l
                  | otherwise     = "#" ++ l
    
    process = snd . mapAccumL processLine False
    
    main = do
      hosts <- readFile "/etc/hosts"
      writeFile "/etc/hosts.backup" hosts
      let newHosts = unlines $ process (lines hosts)
      putStrLn newHosts
      writeFile "/etc/hosts" newHosts
    

    I’m sure this could be done shorter, as everything in Haskell, but I’m just a beginner.

    I then compiled the code and put the binary in my user’s bin folder.

    Since it edits the /etc/hosts file, it has to be run with sudo. I added a line to sudo permissions (run sudo visudo to edit the file) to allow me to run it without a password:

    jacob ALL = NOPASSWD: /Users/jacob/bin/switch_hosts
    

    Then, I added an action to Keyboard Maestro to run sudo /Users/jacob/bin/switch_hosts using a trigger in its system menu. You could do a hotkey trigger or use a TextExpander expansion, or use LaunchBar, or Alfred, or just type it in the Terminal.

    It just was this kind of day. I couldn’t do real work, but I could play a little to make my environment better for when I’ll be able to work.

    Of course, there are commercial products that can help with distraction-free work environment, like Concentrate, which offers this and more. But I prefer to run less applications, if possible.

  • Introducing ReactiveCoreData

    Lately I’ve became seriously interested in the fantastic projects that several bright guys at GitHub open-sourced. I’m talking about ReactiveCocoa and some of its derivatives, like ReactiveCocoaLayout. If you don’t know what these are, first go and read about them. I’ll wait.

    While working on UI code for Cashculator 2, I decided to utilize both of above frameworks and, so far, I’m very happy with my decision. Especially I loved how ReactiveCocoaLayout allowed me to create behaviors similar to Cocoa’s AutoLayout, which I can’t use in Cashculator for performance reasons.

    Like many applications, Cashculator uses Core Data for data persistence. So I had the idea of trying to bring Core Data into the ReactiveCocoa world.

    Thus, ReactiveCoreData (RCD) was born. I’ve already implemented most of the basic functionality that I wanted to include in a hypothetical 1.0. Or is it 0.1. There’s also a proof of concept demo application for the Mac, which shows only a little of how to use it.

    But there are also specs which verify all the functionality, which include easy fetching, insertion, performing stuff on a background context, saving, merging. All of this in the ReactiveCocoa’s signals domain, so it looks neat and can interoperate with your other ReactiveCocoa world.

    A short example:

    RAC(self.filteredParents) = [[[[Parent findAll]
      where:@"name" contains:filterText options:@"cd"]
      sortBy:@"name"]
      fetchWithTrigger:objectsChanged];
    

    This will update filteredParents property (an NSArray) to the all the Parents whose name contains text in the signal filterText (that comes from a search field, for example), sort by name and fetch.

    It will fetch when either the filterText signal sends a next value or when objectsChanged signal fires (it will fire after new Parent objects were added or removed, for example).

    The where: and sortBy: commands modify the NSFetchRequest that’s started with the findAll method of Parent and pass it next. Then, fetch: runs the NSFetchRequest in the current NSManagedObjectContext and sends the NSArray of the result, which gets assigned to self.filteredParents.

    There’s more to ReactiveCoreData than that, but it’s a nice example.

    Check ReactiveCoreData on GitHub.

    I’ll be happy to get any feedback: suggestions, critique, pull requests. Use GitHub, if possible.

    If you prefer to give feedback over Twitter, I’m @apparentsoft. But you better use App.net. I’m @apparentsoft over there as well.

subscribe via RSS