Hi everyone.
I was wondering if anyone can suggest a better solution to a problem I
am trying to solve than one I have come up with. I am trying to create a
friendly user-facing API for accessing custom remote variables.
To explain, consider the following simple class and code:
---===<<< SNIP >>>===---
class A <SomeBase
def initialize
@v = 1
end
def inc
@v = @v + 1
end
def magic
dosomething(@v)
end
attr_accessor :v
end
a = A.new
a.inc
a.magic
---===<<< SNIP >>>===---
Here we have a variable @v that is available for use in each instance of
the class A. We modify it in the instance, and outside of it.
I would like something similar in a user-facing API, where the user can
create a variable v that they can read from and write to, but the catch
is that “v” itself is actually stored remotely in persistent storage.
Each read requests the value from the server, and each write sends it.
The user will define their own variables (such as “v”), and in
presenting the API I won’t know these in advance. Don’t worry about the
storage aspects, networking, serialisation, and cache issues, these are
all written and finished. I’m just trying to provide a nice interface to
the code I’ve already written such that the user can almost ignore the
fact that they are stored remotely.
I’ve written my own “magic_accessor” call to add in a “foo” and “foo=”
method for each variable “foo” (much like attr_accessor), for the user
to use. In this case, we’re just using “v”, which generates the “v” and
“v=” methods when I use it. This changes the above code to the
following.
---===<<< SNIP >>>===---
class A <SomeBase
def initialize
self.v = 1
end
def inc
self.v = v + 1
end
def magic
dosomething(v)
end
magic_accessor :v
end
a = A.new
a.inc
a.magic
---===<<< SNIP >>>===---
What I don’t like with the above is that whenever I set v, I have to be
careful to use "self.v = ", rather than "v = " when I
perform assignment, because the latter will just create a local variable
and not call the “v=” method I’ve created. It’s fine when called
externally on the object, but any internal writes need a “self.” prefix.
I’m not keen on expecting the user to do this each time, when using “@v”
equivalent is so much easier to use.
Is there a better way to implement this, such that the user can write
code similarly to the listing at the top? Is there some syntactic sugar
I am unaware of that can be used instead of “self.foo”? The goal is to
make the user API for this nice and simple- I don’t mind if I have to
mess about to make it happen, and I’ve already got a custom
“method_missing”, and adding code to that is no issue.
Cheers,
Garthy