Created
February 17, 2012 21:43
-
-
Save jgandt/1855631 to your computer and use it in GitHub Desktop.
module ObjectifyFromHash
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Using this as a mix in we are able to maintain a meaningful class structure while exposing the hash keys as viable and visable methods. | |
# I had a lot more I wanted to do in my FileCopyTask, and I didn't feel that the objectification logic was correctly placed in my class. | |
# The really neat part about this is that you could extend an individual instance of an object and objectify it in place. | |
# You could do all sorts of other crazy things with definition of reader/writer/accessor permissions in the objectify call. | |
# This may be entirely useless and silly but I think it is a slightly better option than returning an object of the class Hashit/ObjectifyFromHash | |
OpenStruct is a viable alternative. However, I was unable to find a way to use the Plain class as a mixin. | |
# Thoughts? Comments? Need more of the code around what I'm doing? Is their an easier, clearer way (ActiveModel if working in rails)? | |
# .jpg |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'objectify_from_hash' | |
class FileCopyTask | |
include ObjectifyFromHash | |
def initialize( file_copy_task_as_hash ) | |
objectify file_copy_task_as_hash | |
end | |
# My implementation implements a method similar to this one. This is just a quick example | |
def find_a_source_file | |
# find a file in source dir with the proper file extension. | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
source_directory: copy_from_dir | |
destination_directory: copy_to_dir |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module ObjectifyFromHash | |
def objectify( hash ) | |
hash.each do |k,v| | |
self.instance_variable_set("@#{key}", value) | |
# tcocca was playing with this an noticed that manually defining the methods was both slow and silly. Thanks to Tom for this update: https://gist.github.com/tcocca | |
# Use attr_accessor if you want to allow read-write privileges on the variables. | |
self.class.send(:attr_accessor, key) | |
# Use attr_reader if you only want to allow READ privileges on the variables. | |
#self.class.send(:attr_reader, key) | |
# Use attr_writer if you only want to allow WRITE privileges on the variables. | |
#self.class.send(:attr_writer, key) | |
end | |
end | |
end | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'file_copy_task' | |
# Now use it! | |
# load in a hash from a yaml | |
file_copy_task_hash = YAML::load( File.open('file_copy_task.yml') | |
# => { :source_directory => 'copy_from_dir', :destination_directory => 'copy_to_dir', :file_extension => '.txt' } | |
# Now lets make it a useable object | |
file_copy_task = FileCopyTask.new( file_copy_task ) | |
# => hash keys have now been loaded as attribute accessors. huzzah. use 'em... | |
file_copy_task.source_directory | |
# => 'copy_from_dir' | |
file_copy_task.destination_directory = 'hey_look_a_new_destination_directory' | |
# => 'hey_look_a_new_destination_directory' | |
File.cp( file_copy_task.source_directory + file_copy_task.find_a_source_file, file_copy_task.destination_directory ) |
I did test with attr_accessor. I found significant differences in execution time.
I have not yet jumped into Ruby core to discover the reason, but your explaination is reasonable.
My (very rudimentary) test rig is at https://github.com/jgandt/objectify_from_hash.
Thanks again for your input!
.jpg
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Did you test it with the attr_reader / attr_accessor? Did you see the same speed results that I saw?
My guess is that attr_reader / attr_accessor are doing nothing but looking for instance variables with the same name as the method as opposed to define_method creating an actual method that is using a proc which is lazy loaded and is doing the exact same thing as attr_reader, just looking for / setting an ivar. If you end up investigating i'd love a more in depth answer (mine is just an assumption) but I agree, this is much clearer that the define_method and the massive speedup was a nice bonus!