citizen428.blog()

Try to learn something about everything

Tap Dance

Ruby’s Object#tap is a really nice and useful method. One of my favorite uses is Object#d, which I think I originally saw in irbtools. Personally, I’m using the following version in my ~/.irbrc:

1
2
3
4
5
class Object
  def d
    self.tap { |s| puts s }
  end
end

Inserting this in a chain of calls can be very enlightening as to where a value changes unexpectedly.

However, recently I’ve seen more and more use of tap where I’d traditionally have used inject/reduce. People who know me can attest to the fact that I’m a big fan of the latter, but for some reason there seem to be quite a few developers who find these methods hard to grok. For this reason recent Ruby versions added Enumerable#each_with_object, which seems to be easier to use for some people, but which isn’t very popular because of it’s lengthy name. See for example the following blog post that was written as a result of a discussion I had with the author on StackOverflow: tap vs. each_with_object: tap is faster and less typing.

As I said in the comment there, my main problem is that you have to call tap on what is to become the result, not the data you want to transform. While this is not a problem per se, I somehow don’t like the semantics of it. However, once I decided to hide it behind a Pascal-like with statement, I immediately started liking it:

1
2
3
4
5
module Kernel
  def with(o, &blk)
    o.tap(&blk)
  end
end

Here are the examples from the blog post linked above, including a new version for with. Decide which one you like best:

1
2
3
4
5
6
7
nums.inject({}) { |h, n| h[n] = n ; h }

nums.each_with_object({}) { |n, h| h[n] = n }

{}.tap { |h| nums.each{ |n| h[n] = n } }

with({}) { |h| nums.each { |n| h[n]=n } }

Sure, putting it in Kernel and therefore calling it without a receiver seems a little strange at first, but I kinda like how it reads. I know this is probably a case of me being anal about semantics, but I really think that with transports the intent a lot better than tap in cases like the one shown here.

Information Overload 2012-05-13

SMS is now the world’s most intensively used data communication technology. One source claims that over 6 trillion texts were sent in 2010, for example, and that was more than triple the number sent in 2007.

[M]odern investment bankers are ethically a notch below your average drug dealer. They will extract from their customer – a town, an airline, a chain of retail stores – whatever they think he’ll pay.

Information Overload 2012-05-06

Because groups with wildly different perspectives dominate politics, the observation that ninety-nine per cent of Americans are being left behind economically isn’t of much use politically. The ninety-nine per cent is too big a category to be an effective political force.

Pointless Ruby

It’s no secret that I’m rather fond of functional programming and also try to apply it to my Ruby coding, at least as long as it doesn’t become too unidiomatic.

Being at home sick I got bored, so I played around a bit in IRB to create a composition function that will allow me to create higher-order functions in a pointfree style (sometimes also referred to as “pointless style”, hence the title of this post). I know that Facets has Proc#compose and Proc#*, but they only work with Proc objects. Ruby being the flexible beast that it is, it took me about two minutes to come up with a working solution, which I called fn because it basically returns a function and compose was too long for my taste:

1
2
3
def fn(*funs)
  -> x { funs.inject(x) { |v, f| v.send(f) } }
end

Here it is in action:

1
2
["foo bar", "baz qux"].map &fn(:split, :last)
#=> ["bar", "qux"]

I know that this isn’t really shorter than { |x| x.split.last }, but usefullness isn’t really the goal of a pointless exercise ;-)

So far so good, but if one doesn’t really care about pointfree style, wouldn’t it also be fun to mix and match procs and symbols? It sure would:

1
2
3
4
5
6
7
def fn(*funs)
  -> x do
    funs.inject(x) do |v, f|
      Proc === f ? f.call(v) : v.send(f)
    end
  end
end

Let’s see this in action:

1
2
(1..3).map &fn(:next, -> x { x * x }, -> x { x.to_f / 2 } )
#=> [2.0, 4.5, 8.0]

Note: I’m sick, all of this is untested, does not take into account corner cases of any kind and may harm your pet. It was however a fun little diversion that showed once again how flexible Ruby is.

Information Overload 2012-04-29

You don’t simply get to say you’re not a racist; not being racist — or a sexist or a homophobe — is a constant, arduous process of unlearning, of being uncomfortable, of eating crow and being humbled and re-evaluating.

Information Overload 2012-04-22

Economic development and social stability require freedom of expression, and an independent media to report on issues and abuses that government officials want to sweep under the rug.

Would some kernel people prefer getting tucked in at night instead of being cursed at? I’m sure that would be appreciated. I don’t think I have it in me, though.

No Tor, No More Customer

Update: Server4You rebooted the server into a recovery system for me. I removed the Tor packages and the system is back up again, which means at least the mirror is back. I’d also like to state explicitly that this whole post is based on a single phone conversation with a Server4You support employee, so it’s hard to tell if the company per se really considers Tor to be illegal in Germany. Personally I think it’s just a bad excuse for shutting down the service on shared hosts, which is just as bad in my book.

I’ve been running a Tor relay since sometime in early 2006. There’s many good reasons for doing so, but what motivated me personally was my experience of studying in China for one year and having to live with a censored Internet connection myself (theoretically, as there was an easy way around it if you had a server outside of China to SSH to). Alas our system hasn’t been an exit node in a while, but it’s still better than nothing.

Today I was contacted by my hosting provider’s abuse team, telling me that my server has been shut down because of a ToS violation. I immediately was afraid that they might complain about the Tor relay, but still had hope that I might be wrong. Ten hours later, after I got no reply to about five support requests, I decided to call their hotline. The employee first told me that he has no way to see why the abuse team blocked my server, but then said that running a Tor node may have been the reason. What ensued was a five minute conversation full of WTFs, facepalms and headdesks on my part, but the bottom line is that Server4You is of the opinion that it is illegal to run a Tor relay in Germany because of the “Hackerparagraf”. If you don’t know what that is, read up on recent pushes to enforce similar legislation EU wide.

After a fruitless discussion of said law, the — admittely nice — guy on the phone reassured me that my server will be restarted if I agree to disable the Tor node. I politely told him that I have no interest in using their services at all if I can’t use them the way I want to, so I’ll cancel my contract with Server4You as soon as possible. For the time being I donated some money to Tor, moved my blog over to Heroku (yay Octopress) and started evaluating hosting providers in countries with saner legislation (as long as there still are some).

Sure, there’s probably a lot of really bad things happening over the Tor network, but those shouldn’t be used to discredit the tool’s legitimate uses. If we start blaming technology instead of people, we might as well turn off the Internet.

Information Overload 2012-04-15

Information Overload 2012-04-08

Ich habe also mit meiner Aktion das alteingesessene Bild instituitionalisierter Brauchtums-Macht performativ dekonstruiert. Würde ich aus heutiger Sicht vielleicht sagen. Damals am Christkindlmarkt sagte ich nur “Esmeralda!” und humpelte wie Igor durch die Fleischberge an Touristen.

It’s probably not unrealistic to say that porn makes up 30% of the total data transferred across the internet.

Information Overload 2012-04-01