I’m trying to understand this function.
What I can see is an attribute and type are passed to the opal() method.
Then type_name takes its value from type as long as type is a Symbol or String. Otherwise, the name method is called on type. I imagine the name method is similar to the class method to get the class of the type argument.
After self.class_eval I’m kind of lost but my guess is this is defining maybe a block of code to be added to the class referenced by self.
How this works I’m not sure though.
Would appreciate if someone could explain what’s going on after self.class_eval << DEF.
def opal(attr, type)
self.ds "#{attr}_id"
type_name = (type.is_a?(Symbol) || type.is_a?(String)) ? type : type.name
self.class_eval <<DEF
def #{attr}
if defined?(@#{attr})
@#{attr}
else
@#{attr} = if self.#{attr}_id
#{type_name}.get(self.#{attr}_id)
else
nil
end
end
end
def #{attr}=(value)
self.#{attr}_id = value.key
@#{attr} = value
end
DEF
end
Everything between
<<DEFandDEFis just a string and the#{ ... }s work on that string like any other.class_evalwill cause the interpreter to run on the string in the context of the module.So, if you know what
attrandtypeare then you can work out what code is being run to add methods to the class.Lets say
attris"foo"andtypeis"Bazzle". The code being run would be: