String to symbol

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?

2010/2/12 Sergey S. [email protected]:

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.

 }

end

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.

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?

Kind regards

robert

Robert K. wrote:

2010/2/12 Sergey S. [email protected]:

�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

2010/2/12 Sergey S. [email protected]:

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 = Dates.new(:start=>1,:end=>2,:current=>3)
=> #Dates:0x101bbb5c
irb(main):032:0> d1.start
=> 1
irb(main):033:0> d1.end
=> 2
irb(main):034:0> d1.current
=> 3
irb(main):035:0> d2 = Dates.new(:start=>99,:end=>98,:current=>97)
=> #Dates:0x1017fde4
irb(main):036:0> d2.start
=> 99
irb(main):037:0> d2.end
=> 98
irb(main):038:0> d2.current
=> 97
irb(main):039:0> d1.start # ooops!
=> 99
irb(main):040:0> d1.end # ooops!
=> 98
irb(main):041:0> d1.current # ooops!
=> 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!

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

Kind regards

robert

I referred to passing strings to #initialize. This certainly works.
But the more dramatic issue persists (see above).
Seems like I got it here:
Problem with array in hash - Ruby - Ruby-Forum

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

Kind regards

robert

Sergey S. 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:
Problem with array in hash - Ruby - Ruby-Forum

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

Kind regards

robert
ActiveRecord::Base

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?

On Fri, Feb 12, 2010 at 11:12 AM, Sergey S.
[email protected] 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:
Problem with array in hash - Ruby - Ruby-Forum

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.new{v})
irb(main):005:3> end
irb(main):006:2> end
irb(main):007:1> end
=> nil
irb(main):008:0> t = Task.new(:id => 1)
=> #Task:0xb7d4aca8
irb(main):009:0> t.id
=> 1
irb(main):010:0> t2 = Task.new(:id => 2)
=> #Task:0xb7d3ecdc
irb(main):012:0> t.id
=> 1
irb(main):013:0> t2.id
=> 2

Jesus.