Option 1
I can't recommend this except for fun, but it mostly has the effect you are after:
entry.each |k, v|
singleton_class.send(:attr_accessor, k)
send("#{k}=", v)
end
director # => "Chris Nolan"
self.director = "Wes Anderson" # Unfortunately, must use self for assignment
director # => "Wes Anderson"
Instead of creating local variables it defines acccessor methods on the singleton class of the current object, which you can call as if they were local variables.
To make them more "local" you could use singleton_class.remove_method
to remove these methods when you are done with them. You could even try to alias any existing singleton class methods with the same name and restore them afterwards.
Option 2
This is something I use in real code. It requires the ActiveSupport gem which comes with Ruby On Rails but can also be used on its own.
director, producer, writer = entry.values_at('director', 'producer', 'writer')
Unfortunately it requires typing each variable name twice, instead of zero times as you asked for. If you were certain about the order of the values in the hash, you could write:
director, producer, writer = entry.values # Not so good, IMO.
I feel uneasy about this version because now the code that created the hash has a non-obvious responsibility to ensure the hash is in a certain order.
Note
If your goal is just to reduce typing, here is an approach that only requires two more characters per variable access than if they were true local variables:
e = OpenStruct.new(entry)
e.director # => "Chris Nolan"