Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 863349
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 15, 20262026-05-15T09:17:38+00:00 2026-05-15T09:17:38+00:00

I’ve multiply heard Ruby touted for its super spectacular meta-programming capabilities, and I was

  • 0

I’ve multiply heard Ruby touted for its super spectacular meta-programming capabilities, and I was wondering if anyone could help me get started with this problem.

I have a class that works as an “archive” of sorts, with internal methods that process and output data based on an input. However, the items in the archive in the class itself are represented and processed with integers, for performance purposes. The actual items outside of the archive are known by their string representation, which is simply number_representation.to_s(36).

Because of this, I have hooked up each internal method with a “proxy method” that converts the input into the integer form that the archive recognizes, runs the internal method, and converts the output (either a single other item, or a collection of them) back into strings.

The naming convention is this: internal methods are represented by _method_name; their corresponding proxy method is represented by method_name, with no leading underscore.

For example:

class Archive

  ## PROXY METHODS ##
  ## input: string representation of id's
  ## output: string representation of id's

  def do_something_with id
    result = _do_something_with id.to_i(36)
    return nil if result == nil
    return result.to_s(36)
  end

  def do_something_with_pair id_1,id_2
    result = _do_something_with_pair id_1.to_i(36), id_2.to_i(36)
    return nil if result == nil
    return result.to_s(36)
  end

  def do_something_with_these ids
    result = _do_something_with_these ids.map { |n| n.to_i(36) }
    return nil if result == nil
    return result.to_s(36)
  end

  def get_many_from id
    result = _get_many_from id
    return nil if result == nil         # no sparse arrays returned
    return result.map { |n| n.to_s(36) }
  end

  ## INTERNAL METHODS ##
  ## input: integer representation of id's
  ## output: integer representation of id's

  private

  def _do_something_with id
    # does something with one integer-represented id,
    # returning an id represented as an integer
  end

  def do_something_with_pair id_1,id_2
    # does something with two integer-represented id's,
    # returning an id represented as an integer
  end

  def _do_something_with_these ids
    # does something with multiple integer ids,
    # returning an id represented as an integer
  end

  def _get_many_from id
    # does something with one integer-represented id,
    # returns a collection of id's represented as integers
  end
end

There are a couple of reasons why I can’t just convert them if id.class == String at the beginning of the internal methods:

  1. These internal methods are somewhat computationally-intensive recursive functions, and I don’t want the overhead of checking multiple times at every step
  2. There is no way, without adding an extra parameter, to tell whether or not to re-convert at the end
  3. I want to think of this as an exercise in understanding ruby meta-programming

Does anyone have any ideas?


edit

The solution I’d like would preferably be able to take an array of method names

@@PROXY_METHODS = [:do_something_with, :do_something_with_pair,
                   :do_something_with_these, :get_many_from]

iterate through them, and in each iteration, put out the proxy method. I’m not sure what would be done with the arguments, but is there a way to test for arguments of a method? If not, then simple duck typing/analogous concept would do as well.


I’ve come up with my own solution, using #class_eval

@@PROXY_METHODS.each do |proxy|
  class_eval %{ def #{proxy} *args
                  args.map! do |a|
                    if a.class == String
                      a.to_i(36)
                    else
                      a.map { |id| id.to_i(36) }
                    end
                  end
                  result = _#{proxy}(*args)

                  result and if result.respond_to?(:each)
                               result.map { |r| r.to_s(36) }
                             else
                               result.to_s(36)
                             end
                end
              }
end

However, #class_eval seems a bit…messy? or inelegant compared to what it “should” be.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-15T09:17:39+00:00Added an answer on May 15, 2026 at 9:17 am
    class Archive
      # define a new method-creating method for Archive by opening the
      # singleton class for Archive
      class << Archive
        private # (make it private so no one can call Archive.def_api_method)
        def def_api_method name, &defn
          define_method(name) do |*args|
            # map the arguments to their integer equivalents,
            # and pass them to the method definition
            res = defn[ *args.map { |a| a.to_i(36) } ]
            # if we got back a non-nil response, 
            res and if res.respond_to?(:each)
                      # map all of the results if many returned
                      res.map { |r| r.to_s(36) } 
                    else
                      # map the only result if only one returned
                      res.to_s(36)
                    end
          end
        end
      end
      def_api_method("do_something_with"){ |id| _do_something_with(id) }
      def_api_method("do_something_with_pair"){ |id_1, id_2| _do_something_with_pair id_1.to_i(36), id_2.to_i(36) }
      #...
    end
    

    Instead of opening the singleton to define Archive.def_api_method, you could define it simply using

    class Archive
      def Archive.def_api_method
        #...
    

    But the reason I didn’t do that is then anyone with access to the Archive class could invoke it using Archive.def_api_method. Opening up the singleton class allowed me to mark def_api_method as private, so it can only be invoked when self == Archive.

    If you’re always going to be calling an internal version with the same (or derivable) name, then you could just invoke it directly (rather than pass a definition block) using #send.

    class Archive
      # define a method-creating method that wraps an internal method for external use
      class << Archive
        private # (make it private so no one can call Archive.api_method)
        def api_method private_name
          public_name = private_name.to_s.sub(/^_/,'').to_sym
          define_method(public_name) do |*args|
            # map the arguments to their integer equivalents,
            # and pass them to the private method
            res = self.send(private_name, *args.map { |a| a.to_i(36) })
            # if we got back a non-nil response, 
            res and if res.respond_to?(:each)
                      # map all of the results if many returned
                      res.map { |r| r.to_s(36) } 
                    else
                      # map the only result if only one returned
                      res.to_s(36)
                    end          end
          # make sure the public method is publicly available
          public public_name
        end
      end
    
      api_method :_do_something_with
      api_method :_do_something_with_pair
    
      private
    
      def _do_something_with
        #...
      end
      def _do_something_with_pair
        #...
      end
    end
    

    This is more like what is done by other meta-methods like attr_reader and attr_writer.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 512k
  • Answers 512k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer I think what you want can be achieved by prototyping… May 16, 2026 at 5:36 pm
  • Editorial Team
    Editorial Team added an answer You can't check for any application, but you can actually… May 16, 2026 at 5:35 pm
  • Editorial Team
    Editorial Team added an answer HTML by itself will not do the trick. You will… May 16, 2026 at 5:35 pm

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Related Questions

link Im having trouble converting the html entites into html characters, (&# 8217;) i
Does anyone know how can I replace this 2 symbol below from the string
I am currently running into a problem where an element is coming back from
Seemingly simple, but I cannot find anything relevant on the web. What is the
this is what i have right now Drawing an RSS feed into the php,
I'm trying to decode HTML entries from here NYTimes.com and I cannot figure out
That's pretty much it. I'm using Nokogiri to scrape a web page what has
I have just tried to save a simple *.rtf file with some websites and
I want to count how many characters a certain string has in PHP, but
I ran into a problem. Wrote the following code snippet: teksti = teksti.Trim() teksti

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.