Could you tell me if this is good meta programming style?

Discussion in 'Ruby' started by Vincent Foley, Apr 29, 2005.

  1. Hi everyone,

    I finished playing yet another game of Chrono Trigger the other day,
    and I thought I would look at how I could implement a simple Character
    system in Ruby. I have the following initialize method, but I would
    like to be sure it's not extremely bad style:

    class Character
    attr_accessor :strength, :magic, :defense, :magic_defense

    def initialize(args = {})
    args.each do |k, v|
    instance_variable_set("@#{k}", v) if respond_to?(k)
    end

    methods.grep(/\w=$/).each { |setter|
    getter = setter[0..-2]
    if send(getter).nil?
    send(setter, 0)
    end
    }
    end
    end

    So, if I added a :critical_rate accessor, I wouldn't need to modify
    anything else in the initialize method. Also, I don't want nil in any
    attribute. Is this good style? Are there other (maybe better) ways to
    accomplish this? Thank you.
    Vincent Foley, Apr 29, 2005
    #1
    1. Advertising

  2. Vincent Foley

    Guest

    On Fri, 29 Apr 2005, Vincent Foley wrote:

    > Hi everyone,
    >
    > I finished playing yet another game of Chrono Trigger the other day,
    > and I thought I would look at how I could implement a simple Character
    > system in Ruby. I have the following initialize method, but I would
    > like to be sure it's not extremely bad style:
    >
    > class Character
    > attr_accessor :strength, :magic, :defense, :magic_defense
    >
    > def initialize(args = {})
    > args.each do |k, v|
    > instance_variable_set("@#{k}", v) if respond_to?(k)
    > end
    >
    > methods.grep(/\w=$/).each { |setter|
    > getter = setter[0..-2]
    > if send(getter).nil?
    > send(setter, 0)
    > end
    > }
    > end
    > end
    >
    > So, if I added a :critical_rate accessor, I wouldn't need to modify
    > anything else in the initialize method. Also, I don't want nil in any
    > attribute. Is this good style? Are there other (maybe better) ways to
    > accomplish this? Thank you.


    using my attributes module this would be

    harp:~ > cat a.rb
    require 'yaml'
    require 'attributes'

    class Character
    attributes %w( strength magic defense magic_defense )

    def initialize args = {}
    args.each{|k,v| send k, v if respond_to? k}
    reader_attributes.each{|at| send at, 0 unless send at}
    end
    end

    c = Character::new 'strength' => 4, 'magic' => 2
    y c

    harp:~ > ruby a.rb
    --- !ruby/object:Character
    defense: 0
    magic: 2
    magic_defense: 0
    strength: 4

    this works because an attribute's reader delegates to the writer if called with
    an argument (send at, 0).

    not sure if this is 'better' but it's shorter ;-)

    cheers.

    -a
    --
    ===============================================================================
    | email :: ara [dot] t [dot] howard [at] noaa [dot] gov
    | phone :: 303.497.6469
    | renunciation is not getting rid of the things of this world, but accepting
    | that they pass away. --aitken roshi
    ===============================================================================
    , Apr 29, 2005
    #2
    1. Advertising

  3. la, 2005-04-30 kello 00:14, Vincent Foley kirjoitti:
    > Hi everyone,
    >
    > I finished playing yet another game of Chrono Trigger the other day,
    > and I thought I would look at how I could implement a simple Character
    > system in Ruby. I have the following initialize method, but I would
    > like to be sure it's not extremely bad style:
    >
    > class Character
    > attr_accessor :strength, :magic, :defense, :magic_defense
    >
    > def initialize(args = {})
    > args.each do |k, v|
    > instance_variable_set("@#{k}", v) if respond_to?(k)
    > end
    >
    > methods.grep(/\w=$/).each { |setter|
    > getter = setter[0..-2]
    > if send(getter).nil?
    > send(setter, 0)
    > end
    > }
    > end
    > end
    >
    > So, if I added a :critical_rate accessor, I wouldn't need to modify
    > anything else in the initialize method. Also, I don't want nil in any
    > attribute. Is this good style? Are there other (maybe better) ways to
    > accomplish this? Thank you.


    Hello,
    I've been using a pretty similar class for my config needs, maybe the
    biggest difference is that I'm using a default_config method to get the
    default values and to make it work properly with subclassing.

    I quite like the respond_to?-check you've got there, think I'll extend
    mine by raising a name error if the setter doesn't exist.. or just use a
    config block more often :|

    Anyhow, here's the class:

    class Configurable

    def initialize(config = {}, &optional_config_block)
    config = default_config.merge(config)
    config.each{|k,v| instance_variable_set("@#{k}", v)}
    optional_config_block.call(self) if block_given?
    end

    def default_config
    {}
    end

    end

    #subclassing:

    class Foo < Configurable
    attr_accessor :foo

    def default_config
    super.merge({
    :foo => 10
    })
    end
    end

    Foo.new :foo => 5
    Foo.new{|f| f.foo = 5 }

    class FooBar < Foo
    attr_accessor :bar

    def default_config
    super.merge({
    :bar => 20
    })
    end
    end

    fb = FooBar.new
    fb.foo #=> 10
    fb.bar #=> 20
    Ilmari Heikkinen, Apr 29, 2005
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. micky
    Replies:
    2
    Views:
    1,225
    Scott Allen
    Dec 17, 2005
  2. 322322
    Replies:
    3
    Views:
    294
    James Kanze
    Mar 30, 2008
  3. Rainer Grimm
    Replies:
    1
    Views:
    171
    Steven D'Aprano
    Jul 16, 2011
  4. Erik Veenstra

    Meta-Meta-Programming

    Erik Veenstra, Feb 7, 2006, in forum: Ruby
    Replies:
    29
    Views:
    347
    Erik Veenstra
    Feb 8, 2006
  5. Erik Veenstra

    Meta-Meta-Programming, revisited

    Erik Veenstra, Jul 21, 2006, in forum: Ruby
    Replies:
    21
    Views:
    417
    Erik Veenstra
    Jul 25, 2006
Loading...

Share This Page