The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
One Small Flask of Metaprogramming Elixir

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Red Handed

Posts: 1158
Nickname: redhanded
Registered: Dec, 2004

Red Handed is a Ruby-focused group blog.
One Small Flask of Metaprogramming Elixir Posted: Nov 29, 2005 1:00 AM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Red Handed.
Original Post: One Small Flask of Metaprogramming Elixir
Feed Title: RedHanded
Feed URL: http://redhanded.hobix.com/index.xml
Feed Description: sneaking Ruby through the system
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Red Handed
Latest Posts From RedHanded

Advertisement

We could make metaprogramming easier for the common streetsfolk. I’m not giving a triumphant answer here. I’m just wondering what else you knobbly ducks out there have done like this.

So you have this class which defines a structure for scripts within a larger program (MouseHole in this case):

 class UserScript
   attr_accessor :title, :description, :version, :mount,
                 :register_uri, :rewrite
   def initialize
     @register_uri, @rewrite = [], {}
   end
 end

Nothing special. But the initialize does tell us that register_uri and rewrite are an array and a hash, respectively.

Use a method_missing to set the accessors based on their defaults in initialize:

 meta_make(UserScript) do
   title "MouseCommand" 
   description "A-wiki-and-a-shell-in-one." 
   version "2.0" 

   mount :cmd do
     %{ .. }
   end

   rewrite HTML, XML do
     document.change_someways!
   end

   rewrite CSS do
     document.gsub! '.title', '.titleSUPERIOR'
   end

   # allow methods to be defined
   def to_gravy; end
 end

So, since rewrite was set up in initialize as a hash, the definition above will result in:

 @title = "MouseCommand" 
 @description = "A-wiki-and-a-shell-in-one." 
 @version = "2.0" 
 @mount = [:cmd, #],
 @rewrite = {
   HTML => #,
   XML => #,
   CSS => #
 }

It’s very Railsish, but as people are now so accustomed to that syntax, it could ease transition of Railsers to your project, whatever it be.

Here’s the meta_make method:

 def meta_make(klass, &blk)
   o = klass.new
   (class << o; self; end).instance_eval { @__obj = o }
   class << o
     def self.method_missing(m, *args, &blk)
       set_attr(m, *args, &blk)
     end
     def self.set_attr(m, *args, &blk)
       if blk
         args << nil if args.empty?
         args << blk 
       end
       v = @__obj.instance_variable_get("@#{m}")
       if v.respond_to? :to_ary
         (v = v.to_ary).push args
       elsif v.respond_to? :to_hash
         v = v.to_hash
         while args.length > 1
           v[args.unshift] = args.last
         end
       elsif args.length <= 1
         v = args.first
       else
         v = args
       end
       @__obj.instance_variable_set("@#{m}", v)
     end
   end
   (class << o; self; end).class_eval &blk
   o
 end

Read: One Small Flask of Metaprogramming Elixir

Topic: Dabble demo Previous Topic   Next Topic Topic: I don't need this emacs function anymore... but you might like it

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use