Hi. Consider the ruby-hmac gem:
http://pastie.org/580360
Line 81 makes the following call:
hmac = self.new(key)
But, insofar as I understand Ruby's wonderful world context switching,
self, in the instance in which it is called, is both unnecessary
On first inspection, yes. But not if you look closer:
(because the method in which it is being called is already part of the
class) and incorrect (because the only initialize method available
requires more than one argument).
The method invoked is #new and not #initialize! This means that argument lists of new and initialize need not be identical. You can create a class whose Method.new has different arguments than #initialize:
class Foo
def self.new(x)
o = allocate
o.send(:initialize, x, 1, 2)
o
end
def initialize(a, b, c)
# ...
end
end
In this case it works differently though:
The file works (in some instances...), so I'll assume my understanding
of Ruby is still poor. Which sucks because I thought I knew it fairly
well.
I've tried printing out self in each new context, and I get the expected
result (HMAC::Base). Except, that is, inside a Rails application running
on Ruby 1.9.1, in which case I get HMAC::SHA1 within the Base.digest
method. Awesome.
Any ideas?
The fact that the class is called "Base" indicates that it is intended for inheritance. I don't have a Ruby interpreter at hand right now to cook up a tested example, but considering inheritance and the fact that class methods are inherited by subclasses the whole thing actually makes sense:
class SHA1 < Base
def initialize(key)
super(SHA1, 1024, 4096, key)
end
end
Now line 99 makes sense in combination with 81 / 91: Base.new is private which will make self.new() trigger an exception and thus prevent invocation of Base.digest() and Base.hexdigest(). But, you can invoke SHA1.digest() and it will work.
Arguments algorithm, block_size and output_length to Base.initialize are actually class dependent, i.e. every subclass likely defines their own values.
Kind regards
robert
···
On 11.08.2009 21:23, Daniel Waite wrote:
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/