Using a block to configure/initialize a class

Hi! i need a solution for this, it’s pretty simple but i can’t get it to
work…

suppose:

class Options

def self.define_an_option
# …don’t-know-how-implementation :frowning:
end

define_an_option :option1, String
define_an_option :option2, Array
end

Then, i want to do something like this:

opt= Options.new
opt.option1 => “”
opt.option2 => []

opt.option1 do |o|
o= “Hello”
end

opt.option2 do |o|
o << 10
end

options.option1 => “Hello”
options.option2 => [10]

Thats all! Seems pretty simple, but i tried with a lot of variants and I
don’t get it to work. Any ideas?

Thanks!

From: [email protected] [mailto:[email protected]] On Behalf
Of
Emmanuel O.
Sent: Wednesday, September 26, 2007 1:09 AM

end

Before you do it, you should understand your API examples seems
unnatural.

Why not to do

opt.option1 = “Hello”
opt.option2 << 10

?

Than, this example:

opt.option1 do |o|
o = “Hello”
end

is almost impossible to do (possible, but hard), because it should read
like: “pass reference option value into block though ‘o’ variable;
replace
‘o’ with reference to ‘Hello’ string” - option value will left
untouched.

V.

Hi –

On Wed, 26 Sep 2007, Emmanuel O. wrote:

opt.option1 do |o|
o= “Hello”
end

That’s just a re-assignment to the variable ‘o’. It’s not going to
have any impact on opt.option1.

opt.option2 do |o|
o << 10
end

options.option1 => “Hello”
options.option2 => [10]

Thats all! Seems pretty simple, but i tried with a lot of variants and I
don’t get it to work. Any ideas?

The block syntax seems a little odd. Is there any reason not to just
use attr_accessor? If you want it to default to a new instance of some
specific class, you could do something like:

class Options

def self.define_an_option(name, klass)
attr_writer name
iv = “@#{name}”
define_method(name) do
unless instance_variables.include?(iv)
instance_variable_set(iv, klass.new)
end
val = instance_variable_get(iv)
yield val if block_given? # if you really need this
val
end
end

define_an_option :option1, String
define_an_option :option2, Array
end

(and I suspect there are other versions of attr_reader with a default
value out there somewhere).

David

Hi! thanks for you replies. I’m going to analyze them. For the moment i
wanted to answer the question of the unnatural api. The reason i wan’t
to do it that way is because i’m not going to use String or array for
most of the options, but Structs. So i want a way to let the user do
this

Struct.new “Value”, :sub1, :sub2, :sub3 << In fact, the user may not
even know about the Struct::Value class.

class Options
…same as before…
define_option :an_option
end

opt= Options.new

opt.an_option do |o|
o.sub1= …
o.sub2= …
o.sub3= …
end

instead of

an_option.sub1= …
an_option.sub2= …
an_option.sub3= …

On Sep 25, 2007, at 6:09 PM, Emmanuel O. wrote:

end

Thats all! Seems pretty simple, but i tried with a lot of variants
and I
don’t get it to work. Any ideas?

Have you looked at the built-in class Struct? I think it will supply
what you need.

Options = Struct.new(:option1, :option2) opt=Options.new("", []) opt.option1 = "Hello" opt.option2 << 10 < "Hello" opt.option2 # => [10, 42]

Regards, Morton

From: [email protected] [mailto:[email protected]] On Behalf
Of
Emmanuel O.
Sent: Wednesday, September 26, 2007 2:51 AM

class Options
end

instead of

an_option.sub1= …
an_option.sub2= …
an_option.sub3= …

Acceptable explanation. Then, trying to answer:

  1. Defining the method you need “by hands”:

class Option
def an_option
@an_option ||= Value.new
yield @an_option if block_given?
@an_option
end
end

  1. Designing #define_option

class Option
def self.define_option(name, type)
class_eval %Q{
def #{name}
@#{name} ||= #{type.inspect}.new
yield @#{name} if block_given?
@#{name}
end
}
end

define_option :an_option, Array
end

o = Option.new

p o.an_option # => []

o.an_option { |opt|
opt << 1 << 2 << 3
}

p o.an_option # => [1,2,3]

Really, I think it can be done with more grace (without textual eval).

V.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs