lib/rant/rantvar.rb in rant-0.3.8 vs lib/rant/rantvar.rb in rant-0.4.0

- old
+ new

@@ -14,11 +14,11 @@ # thus it acts as a namespace. # # If you're looking for general info about Rant, read the # README[link:files/README.html]. module Rant - VERSION = '0.3.8' + VERSION = '0.4.0' # Those are the filenames for rantfiles. # Case matters! RANTFILES = [ "Rantfile", "rantfile", @@ -43,9 +43,70 @@ end # This module is a namespace for generator classes. module Generators end + + @__rant_no_value__ = Object.new.freeze + def self.__rant_no_value__ + @__rant_no_value__ + end + + module MetaUtils + # Creates two accessor methods: + # obj.attr_name:: Return value of instance variable + # @attr_name + # obj.attr_name = val:: Set value instance variable + # @attr_name to val + # obj.attr_name val:: same as above + def rant_attr attr_name + attr_name = valid_attr_name attr_name + attr_writer attr_name + module_eval <<-EOD + def #{attr_name} val=Rant.__rant_no_value__ + if val.equal? Rant.__rant_no_value__ + @#{attr_name} + else + @#{attr_name} = val + end + end + EOD + nil + end + # Creates accessor methods like #rant_attr for the attribute + # attr_name. Additionally, values are converted with to_str + # before assignment to instance variables happens. + def string_attr attr_name + attr_name = valid_attr_name attr_name + module_eval <<-EOD + def #{attr_name}=(val) + if val.respond_to? :to_str + @#{attr_name} = val.to_str + else + raise ArgumentError, + "string (#to_str) value required", caller + end + end + def #{attr_name} val=Rant.__rant_no_value__ + if val.equal? Rant.__rant_no_value__ + @#{attr_name} + else + self.__send__(:#{attr_name}=, val) + end + end + EOD + nil + end + # attr_name is converted to a string with #to_s and has to + # match /^\w+$/. Returns attr_name.to_s. + def valid_attr_name attr_name + attr_name = attr_name.to_s + attr_name =~ /^\w+$/ or + raise ArgumentError, + "argument has to match /^\w+$/", caller + attr_name + end + end # module MetaUtils module RantVar class Error < RantError end