Hello --

On Mon, 12 Nov 2001, Massimiliano Mirra wrote:

> I'm a newcomer to dynamic languages and have found quite an incredible
> world among Ruby's .call, .method_missing and so on.  I've been
> playing a bit to learn these features and I'd like comments from more
> experienced folks on this bit of code.

[...]

> The one thing I would have liked to do but have not been able to, was
> of using :symbol's instead of strings as keys for the @formulas hash.
> The difficulty arose in method_missing when trying to get the :symbol
> from the variable (didn't find anything that looks like
> "a".to_symbol).  I don't know whether it would have made any
> difference in performance, though.  I don't even know if in terms of
> performance it is any good, for that matter.  But, as I said, I was
> mostly playing. :-)

You're looking for String#intern.

Now, there are easier ways to organize code to calculate the area
of triangles :-)  However, in the spirit of play and learning, here's
some tweakage of your code, perhaps with a few things you might find
helpful or informative:

#!/bin/ruby -w

class Triangle
  # If you're not going to use the reader methods, then
  # you can just do this:
  attr_writer :base, :height, :area

  def initialize(b=4.0,h=5.0,a=10.0)
    @base = b
    @height = h
    @area = a
    @formulas = {
      :area   => Proc.new { @base * @height / 2.0 },
      :base   => Proc.new { @area * 2 / @height.to_f },
      :height => Proc.new { @area * 2 / @base.to_f }
    }
    @solve_prefix = "solve_for_"
  end

  # A bit of tightening up of code:
  def method_missing(method_id, *args)
    if /^#{@solve_prefix}(.*)/.match(method_id.to_s)
      solve_for($1)
    else
      super
    end
  end

  def to_s
    "Base: #{@base}\nHeight: #{@height}\nArea: #{@area}\n"
  end

  private

  # (I tend to shorten variable names -- it's just a me thing :-)
  def solve_for(var_name)
    writer = method(var_name + "=") # look for `xxx=' method
    formula = @formulas[var_name.intern]     # get the right formula
    value = formula.call                   # execute it
    writer.call(value)                   # write its value
  end

end


David

-- 
David Alan Black
home: dblack / candle.superlink.net
work: blackdav / shu.edu
Web:  http://pirate.shu.edu/~blackdav