String to symbol

Discussion in 'Ruby' started by Sergey Sheypak, Feb 12, 2010.

  1. Hello, I'm working with yaml and objects.
    Please, see my model:

    #Base class for all models.
    class DataBean
    #list allowed fields for model
    def allowed_fields
    []
    end

    def is_attr_allowed!(attr)
    raise(ValidationException, "Attribute with name [#{attr}] is not
    allowed for model #{self.class}.
    Allowed fields are
    #{allowed_fields}", caller) unless allowed_fields.include?(attr)
    end

    def initialize(options)
    options.each_pair { |attr_name , value|
    is_attr_allowed!(attr_name)
    self.class.send:)define_method, attr_name, Proc.new{value})
    }
    end

    end

    class Dates < DataBean
    def allowed_fields
    [:start, #project beginning
    :end, #project ending
    :current] #last modification date "T", means current date
    end
    end

    So I can use 'rails like intializers'
    Dates.new:)start=>Date.new, :end=>Dates.new+100)

    The problem is that I'm reading Dates class fields from yaml file.

    Dates:
    class: Dates
    fields_ordered: [start, current, end]

    And I pass String (read from yaml) as a hash key to initializer:
    Dates.new('start'=>Date.new)

    As I read, :symbols are constants, they are immutable and have int
    representation. These facts help to spend less memory and resources.

    Do I have any opportunity to pass Strings into my initializers?
    --
    Posted via http://www.ruby-forum.com/.
    Sergey Sheypak, Feb 12, 2010
    #1
    1. Advertising

  2. 2010/2/12 Sergey Sheypak <>:
    > Hello, I'm working with yaml and objects.
    > Please, see my model:
    >
    > #Base class for all models.
    > class DataBean
    > =A0#list allowed fields for model
    > =A0def allowed_fields
    > =A0 =A0[]
    > =A0end
    >
    > =A0def is_attr_allowed!(attr)


    IMHO that method would rather be called ensure_attr_allowed - if you
    call it is_... I would expect it to return a boolean.

    > =A0 =A0raise(ValidationException, "Attribute with name [#{attr}] is not
    > allowed for model #{self.class}.
    > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 A=

    llowed fields are
    > #{allowed_fields}", caller) unless allowed_fields.include?(attr)
    > =A0end
    >
    > =A0def initialize(options)
    > =A0 =A0 =A0options.each_pair { |attr_name , value|
    > =A0 =A0 =A0 =A0is_attr_allowed!(attr_name)
    > =A0 =A0 =A0 =A0self.class.send:)define_method, attr_name, Proc.new{value}=

    )
    > =A0 =A0 =A0}
    > =A0end


    Are you sure this is what you want? It seems you change the accessor
    method for *all* instances to return the *same* value. I don't think
    this is a good idea.

    > end
    >
    > class Dates < DataBean
    > =A0def allowed_fields
    > =A0 =A0[:start, =A0#project beginning
    > =A0 =A0 :end, =A0 =A0#project ending
    > =A0 =A0 :current] #last modification date "T", means current date
    > =A0end
    > end
    >
    > So I can use 'rails like intializers'
    > Dates.new:)start=3D>Date.new, :end=3D>Dates.new+100)
    >
    > The problem is that I'm reading Dates class fields from yaml file.
    >
    > Dates:
    > =A0class: Dates
    > =A0fields_ordered: [start, current, end]
    >
    > And I pass String (read from yaml) as a hash key to initializer:
    > Dates.new('start'=3D>Date.new)
    >
    > As I read, :symbols are constants, they are immutable and have int
    > representation. These facts help to spend less memory and resources.
    >
    > Do I have any opportunity to pass Strings into my initializers?


    Did you try it out with your code? Was there an issue, if so, which one?

    Kind regards

    robert

    --=20
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
    Robert Klemme, Feb 12, 2010
    #2
    1. Advertising

  3. Robert Klemme wrote:
    > 2010/2/12 Sergey Sheypak <>:
    >> �def is_attr_allowed!(attr)

    > IMHO that method would rather be called ensure_attr_allowed - if you
    > call it is_... I would expect it to return a boolean.

    I've added "!" to show that it can throw exception (like in rails)
    >
    > Are you sure this is what you want? It seems you change the accessor
    > method for *all* instances to return the *same* value. I don't think
    > this is a good idea.

    I have a bean. Bean can accept certain fields in his constructor.
    List of certain fields is overriden in each subclass of DataBean.
    I read source (csv) file and try to construct bean using dats from
    source and my bean.

    >
    >> So I can use 'rails like intializers'
    >>
    >> As I read, :symbols are constants, they are immutable and have int
    >> representation. These facts help to spend less memory and resources.
    >>
    >> Do I have any opportunity to pass Strings into my initializers?

    >
    > Did you try it out with your code? Was there an issue, if so, which
    > one?
    >

    Code works fine.
    I've just added to config.yaml:
    ---
    Dates:
    class: Dates
    fields_ordered: [:start, :current, :end]

    and
    @conf = YAML::load( File.open( 'config.yml' ) ) #keeps parsed YAML
    #some code
    #block_name id a current 'top' name like 'Dates'
    @struct[:fields] = @conf[block_name]['fields_ordered']
    #and later...
    private
    def init_hash(arr)
    Hash[*@struct[:fields].collect {|v| [v,
    arr[@struct[:fields].index(v)]]}.flatten]
    end

    It's method for converting csv line:
    lol, 123,lolo, 123.45
    to hash using appopriate bean field names as keys





    > Kind regards
    >
    > robert


    --
    Posted via http://www.ruby-forum.com/.
    Sergey Sheypak, Feb 12, 2010
    #3
  4. 2010/2/12 Sergey Sheypak <>:
    > Robert Klemme wrote:
    >> 2010/2/12 Sergey Sheypak <>:
    >>> =EF=BF=BDdef is_attr_allowed!(attr)

    >> IMHO that method would rather be called ensure_attr_allowed - if you
    >> call it is_... I would expect it to return a boolean.

    > I've added "!" to show that it can throw exception (like in rails)
    >>
    >> Are you sure this is what you want? =C2=A0It seems you change the access=

    or
    >> method for *all* instances to return the *same* value. =C2=A0I don't thi=

    nk
    >> this is a good idea.

    > I have a bean. Bean can accept certain fields in his constructor.
    > List of certain fields is overriden in each subclass of DataBean.
    > I read source (csv) file and try to construct bean using dats from
    > source and my bean.


    I understood that. But the point you are probably missing is this:
    you are mixing class and instance information in an unfortunate way:

    irb(main):031:0* d1 =3D Dates.new:)start=3D>1,:end=3D>2,:current=3D>3)
    =3D> #<Dates:0x101bbb5c>
    irb(main):032:0> d1.start
    =3D> 1
    irb(main):033:0> d1.end
    =3D> 2
    irb(main):034:0> d1.current
    =3D> 3
    irb(main):035:0> d2 =3D Dates.new:)start=3D>99,:end=3D>98,:current=3D>97)
    =3D> #<Dates:0x1017fde4>
    irb(main):036:0> d2.start
    =3D> 99
    irb(main):037:0> d2.end
    =3D> 98
    irb(main):038:0> d2.current
    =3D> 97
    irb(main):039:0> d1.start # ooops!
    =3D> 99
    irb(main):040:0> d1.end # ooops!
    =3D> 98
    irb(main):041:0> d1.current # ooops!
    =3D> 97
    irb(main):042:0>

    You are changing state of an already created instance as a side effect
    of creating a new instance. This is not a good idea!

    >>> So I can use 'rails like intializers'
    >>>
    >>> As I read, :symbols are constants, they are immutable and have int
    >>> representation. These facts help to spend less memory and resources.
    >>>
    >>> Do I have any opportunity to pass Strings into my initializers?

    >>
    >> Did you try it out with your code? =C2=A0Was there an issue, if so, whic=

    h
    >> one?
    >>

    > Code works fine.


    I referred to passing strings to #initialize. This certainly works.
    But the more dramatic issue persists (see above).

    Kind regards

    robert

    --=20
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
    Robert Klemme, Feb 12, 2010
    #4

  5. > I referred to passing strings to #initialize. This certainly works.
    > But the more dramatic issue persists (see above).

    Seems like I got it here:
    http://www.ruby-forum.com/topic/204068

    Is there any opportunity to add attributes to instance, not to class?

    > Kind regards
    >
    > robert


    --
    Posted via http://www.ruby-forum.com/.
    Sergey Sheypak, Feb 12, 2010
    #5
  6. Sergey Sheypak wrote:
    >
    >> I referred to passing strings to #initialize. This certainly works.
    >> But the more dramatic issue persists (see above).

    > Seems like I got it here:
    > http://www.ruby-forum.com/topic/204068
    >
    > Is there any opportunity to add attributes to instance, not to class?
    >
    >> Kind regards
    >>
    >> robert

    http://api.rubyonrails.org/classes/ActiveRecord/Base.html#M002323

    2435: self.class.send:)scope, :create).each { |att,value|
    self.send("#{att}=", value) } if self.class.send:)scoped?, :create)

    Do I need someting like that?
    --
    Posted via http://www.ruby-forum.com/.
    Sergey Sheypak, Feb 12, 2010
    #6
  7. On Fri, Feb 12, 2010 at 11:12 AM, Sergey Sheypak
    <> wrote:
    >
    >> I referred to passing strings to #initialize. =A0This certainly works.
    >> But the more dramatic issue persists (see above).

    > Seems like I got it here:
    > http://www.ruby-forum.com/topic/204068
    >
    > Is there any opportunity to add attributes to instance, not to class?


    Send the define method to the singleton class of the object, instead
    of sending it to the class:

    irb(main):001:0> class Task
    irb(main):002:1> def initialize options
    irb(main):003:2> options.each_pair do |k,v|
    irb(main):004:3* (class << self; self; end).send:)define_method, k, Proc.ne=
    w{v})
    irb(main):005:3> end
    irb(main):006:2> end
    irb(main):007:1> end
    =3D> nil
    irb(main):008:0> t =3D Task.new:)id =3D> 1)
    =3D> #<Task:0xb7d4aca8>
    irb(main):009:0> t.id
    =3D> 1
    irb(main):010:0> t2 =3D Task.new:)id =3D> 2)
    =3D> #<Task:0xb7d3ecdc>
    irb(main):012:0> t.id
    =3D> 1
    irb(main):013:0> t2.id
    =3D> 2

    Jesus.
    Jesús Gabriel y Galán, Feb 12, 2010
    #7
    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. Jeff Kish
    Replies:
    2
    Views:
    906
    Jeff Kish
    Nov 15, 2004
  2. baumann@pan
    Replies:
    1
    Views:
    730
    Richard Bos
    Apr 15, 2005
  3. korean_dave
    Replies:
    2
    Views:
    311
    John Machin
    Jun 17, 2008
  4. Song Ma
    Replies:
    2
    Views:
    220
    Charles Oliver Nutter
    Jul 20, 2008
  5. Replies:
    6
    Views:
    1,726
Loading...

Share This Page