I'm a little tired so I'm probably making a mistake:
module MyModule
class << self
attr_accessor :foo
alias_method :foo?, :foo
# def configure(&block); yield; end # doesn't work
end
end
# doesn't work either #class << MyModule
# def configure(&block); yield; end #end
Thanks in advance for any advice. I'd rather not use any
Active*/Rails-specific method and don't want to use Struct, OpenStruct,
etc. I just want to be able to call the methods created by the
attr_accessor I used to set and get attributes. The reasons I'm doing
this to a module and not a class is it is convenient since it is the
module that my Gem's classes use.
first off, you're not that wrong with your idea. There are two things which need to be changed.
MyModule.configure do
foo = false
end
The local variable foo is just that - a local variable. You want it to be a class instance variable, so you need to precede it with an @.
module MyModule
class << self
attr_accessor :foo
alias_method :foo?, :foo
# def configure(&block); yield; end # doesn't work
end
end
Thanks in advance for any advice. I'd rather not use any
Active*/Rails-specific method and don't want to use Struct, OpenStruct,
etc. I just want to be able to call the methods created by the
attr_accessor I used to set and get attributes. The reasons I'm doing
this to a module and not a class is it is convenient since it is the
module that my Gem's classes use.
You don't need to use an external library. The thing you did wrong in your configure method is that it executes the block in the scope of it's creation, so even if you use the @, it is not a variable in the class/module scope. So what you need to do is call class_eval with the block as a parameter:
def configure( &block ); class_eval █ end
I'm a little tired so I'm probably making a mistake:
module MyModule
class << self
attr_accessor :foo
alias_method :foo?, :foo
# def configure(&block); yield; end # doesn't work
end
end
# doesn't work either #class << MyModule
# def configure(&block); yield; end #end
Thanks in advance for any advice. I'd rather not use any
Active*/Rails-specific method and don't want to use Struct, OpenStruct,
etc. I just want to be able to call the methods created by the
attr_accessor I used to set and get attributes. The reasons I'm doing
this to a module and not a class is it is convenient since it is the
module that my Gem's classes use.
That just creates a block local variable which is destroyed when the
block ends. This block:
MyModule.configure do @foo = false
end
...gets its bindings from the surrounding scope at the time the block
executes, and at that time self is 'main' and the 'main' object has no
method foo=() defined for it.
You could do this:
module MyModule
class <<self
attr_accessor :foo
def configure(hash)
hash.each {|key, val| send(:"#{key}=", val)}
end
end
end
p MyModule.foo
MyModule.configure 'foo' => false
p MyModule.foo
That just creates a block local variable which is destroyed when the
block ends.
Is there a way to make things in the block execute as if they were being
called on MyModule, i.e.
MyModule.foo = 1
MyModule.bar = 2
could be alternatively:
MyModule.do
foo = 1
bar = 2
end
You could do this:
module MyModule
class <<self
attr_accessor :foo
def configure(hash)
hash.each {|key, val| send(:"#{key}=", val)}
end
end
end
p MyModule.foo
MyModule.configure 'foo' => false
p MyModule.foo
--output:--
nil
false
That is helpful, but I have a way to do a hash easily already via
another method, with the idea that the following might be interesting:
MyModule.do
foo = 1
def bar
2 # imagine a more interesting and dynamic result
end
end
I understand it might require some changes, so syntax might not be
exactly like that, but originally I thought this would be doable, and am
just kind of stuck. Ilia had suggested ActiveSupport::Configurable on
the list but it requires config to be sent in as a parameter and I was
hoping to allow method definition and not have to specify the
config.varname = ...
first off, you're not that wrong with your idea. There are two things
which need to be changed.
MyModule.configure do
foo = false
end
The local variable foo is just that - a local variable. You want it to
be a class instance variable, so you need to precede it with an @.
etc. I just want to be able to call the methods created by the
attr_accessor I used to set and get attributes. The reasons I'm doing
this to a module and not a class is it is convenient since it is the
module that my Gem's classes use.
You don't need to use an external library. The thing you did wrong in
your configure method is that it executes the block in the scope of it's
creation, so even if you use the @, it is not a variable in the
class/module scope. So what you need to do is call class_eval with the
block as a parameter:
def configure( &block ); class_eval █ end
Calvin,
Thanks! That is even shorter. It is nice to have both options available,
so when do:
module MyModule
class << self
attr_accessor :foo
alias_method :foo?, :foo
def configure(&blk)
class_eval(&blk)
end
end
end
can do either:
MyModule.configure do @foo = false
def self.time; Time.now; end
end
or
MyModule.configure do
self.foo = false
def self.time; Time.now; end
end
I don't know if my previous message got through. If you can handle
some changes in the syntax, using self. before the attributes and the
method names should work if you do a class_eval:
1.9.2p290 :013 > module MyModule
1.9.2p290 :014?> class << self
1.9.2p290 :015?> attr_accessor :foo
1.9.2p290 :016?> alias_method :foo?, :foo
1.9.2p290 :017?> def configure(&blk)
1.9.2p290 :018?> class_eval(&blk)
1.9.2p290 :019?> end
1.9.2p290 :020?> end
1.9.2p290 :021?> end
=> nil
1.9.2p290 :022 > MyModule.configure do
1.9.2p290 :023 > def self.test; puts "test"; end
1.9.2p290 :024?> end
=> nil
1.9.2p290 :025 > MyModule.test
test
=> nil
Jesus.
···
On Wed, Sep 26, 2012 at 10:41 PM, Gary Weaver <lists@ruby-forum.com> wrote:
7stud -- wrote in post #1077677:
MyModule.configure do
foo = false
end
That just creates a block local variable which is destroyed when the
block ends.
Is there a way to make things in the block execute as if they were being
called on MyModule, i.e.
MyModule.foo = 1
MyModule.bar = 2
could be alternatively:
MyModule.do
foo = 1
bar = 2
end
You could do this:
module MyModule
class <<self
attr_accessor :foo
def configure(hash)
hash.each {|key, val| send(:"#{key}=", val)}
end
end
end
p MyModule.foo
MyModule.configure 'foo' => false
p MyModule.foo
--output:--
nil
false
That is helpful, but I have a way to do a hash easily already via
another method, with the idea that the following might be interesting:
MyModule.do
foo = 1
def bar
2 # imagine a more interesting and dynamic result
end
end
I understand it might require some changes, so syntax might not be
exactly like that, but originally I thought this would be doable, and am
just kind of stuck. Ilia had suggested ActiveSupport::Configurable on
the list but it requires config to be sent in as a parameter and I was
hoping to allow method definition and not have to specify the
config.varname = ...
"Jesús Gabriel y Galán" <jgabrielygalan@gmail.com> wrote in post #1077681:
You could do this:
That is helpful, but I have a way to do a hash easily already via
exactly like that, but originally I thought this would be doable, and am
just kind of stuck. Ilia had suggested ActiveSupport::Configurable on
the list but it requires config to be sent in as a parameter and I was
hoping to allow method definition and not have to specify the
config.varname = ...
I don't know if my previous message got through. If you can handle
some changes in the syntax, using self. before the attributes and the
method names should work if you do a class_eval:
1.9.2p290 :013 > module MyModule
1.9.2p290 :014?> class << self
1.9.2p290 :015?> attr_accessor :foo
1.9.2p290 :016?> alias_method :foo?, :foo
1.9.2p290 :017?> def configure(&blk)
1.9.2p290 :018?> class_eval(&blk)
1.9.2p290 :019?> end
1.9.2p290 :020?> end
1.9.2p290 :021?> end
=> nil
1.9.2p290 :022 > MyModule.configure do
1.9.2p290 :023 > def self.test; puts "test"; end
1.9.2p290 :024?> end
=> nil
1.9.2p290 :025 > MyModule.test
test
=> nil
Jesus.
Thank you, Jesus! That's exactly what I was looking for!
module MyModule
class << self
attr_accessor :foo, :time
alias_method :foo?, :foo
def configure(&blk)
class_eval(&blk)
end
end
end
MyModule.foo # nil
MyModule.time # nil
MyModule.configure do
self.foo = false
def self.time; Time.now; end
end
MyModule.foo # false
MyModule.time # current date and time
Gary
···
On Wed, Sep 26, 2012 at 10:41 PM, Gary Weaver <lists@ruby-forum.com> > wrote: