[ANN] FaceToFace 0.1.0

B

benny

Benny is happy to announce his first published piece of software:
"FaceToFace" available as gem.


Dear list,

I hope this is useful for someone and I am curious what you think about it.

The code itself is no big deal and always open for improvements (as my
english is).

= Overview

FaceToFace aims to standardize the conversion and messaging
between classes and objects.

You may think of it as syntactic sugar and as duck-typing taken to
the next level (imagine two ducks face to face, none of them being a real
duck).

Up to now we had to remember each method that converts to a
certain class, e.g. 'to_i' converts to Integer, 'to_s' converts to String
etc.

With FaceToFace you only have to remember one method and
you need to know the class to convert to, e.g.
5.to(String ) #=> "5"
"6".to( Integer ) #=> 6

That way you could double-ducktype, i.e. you may not care
about the class of any object you convert to or from, e.g.
def double_duck_me( duck1, duck2 )
duck1.to( duck2.class_name )
end

Instead of using to() you could also use from() to access the result of a
conversion, e.g.
Array.from( "test" ) #=> ["test"]
String.from( 4 ) #=> "4"

Furthermore you can pass objects instead of classes as well
5.to( "" ) #=> "5"
"6".from( 4 ) #=> "4"

This allows you to pass messages between objects and modify them completely
or partially, e.g.
class MyClass
attr_accessor :message, :data
end

class YourClass
attr_accessor :message, :data
end

MyClass.register_from( YourClass ) do |my, your|
my.message = your.data
my
end

my = MyClass.new
my.data = "my Data"
your = YourClass.new
your.data = "your Data"

my.from( your )
#=> #<MyClass:0x806c56c @data="my Data", @message="your Data">

== Benefits

+ Unfied way to define Object / Class conversions
+ Ability to seperate the code of conversion methods from the classes
itself for continuous optimization/version-replacement
+ "blind" conversion to/from foreign classes
+ indirect conversion via slots in the future
+ you don't have to invent new methods each time you need to define a
conversion
- maybe performance
- a little more effort to define the conversion methods

== Future

In the near future there will be a Slot class that is meant to be an
Interface to most of the core types/classes.

If two classes have a conversion method to/from the same Slot, it will be
possible to convert them into each other via this Slot. This should
sometimes eliminate the need of direct or multiple conversion.

== Installation
gem install FaceToFace --remote

== Example of usage
require 'rubygems'
require_gem 'FaceToFace'
# not needed but recommended (registers to_a, to_s and the like)
require 'basic_registration'

# registration of the conversion methods of self defined classes, e.g.
MyClass.register_from( YourClass ) do |my, your|
my.message = your.data
my.message
end

MyClass.register_to( YourClass ) do |my, your|
your.message = my.data
your.message
end

# You may overwrite singleton methods for objects and classes
class MyClass
def initialize(data)
@data = data
end

def MyClass.from(obj, via=nil)
FaceToFace::Registry.from( (self.new(obj.message) ), obj, via )
end
end

your.message = "your Message"
MyClass.from( your )
#=> #<MyClass:0x810d8d8 @data="your Message", @message="your Data">

----------------------------------------
Project Website: http://rubyforge.org/projects/facetoface
Contact: (e-mail address removed)

benny

---------------------------------------------------------------------------------------------------
Don't crash when a filter changes the subject of a message which results
in the attempt to remove it from the tree of subject threading messages
failing and the detached child looking for a new parent finding the old
parent as the new parent, which in turn results in the child being deleted
with the old (and new) parent, which is not a good idea, since it is
still referenced.

(Till Adams commit on kdepim/kmail/kmheaders.cpp in HEAD, 6. Jan. 2005)
 
P

Pit Capitain

benny said:
Benny is happy to announce his first published piece of software:
"FaceToFace" available as gem.

Very nice. One question: how is the return value of the conversion code used?
MyClass.register_from( YourClass ) do |my, your|
my.message = your.data
my
end

A second example:
MyClass.register_from( YourClass ) do |my, your|
my.message = your.data
my.message
end

Just a remark:
In the near future there will be a Slot class that is meant to be an
Interface to most of the core types/classes.

If two classes have a conversion method to/from the same Slot, it will be
possible to convert them into each other via this Slot. This should
sometimes eliminate the need of direct or multiple conversion.

I think the name "Slot" could be misleading. (See previous discussions about the
term "slot" in this mailing list.) Or are you planning to nest the name "Slot"
in a namespace as in "FaceToFace::Slot"?

Regards,
Pit
 
A

Alexander Staubo

benny said:
FaceToFace aims to standardize the conversion and messaging
between classes and objects.

By the usual nomenclature this is an adapter framework -- why not call a
spade a spade? :)

Looks elegantly implemented, though. Ruby definitely needs something
like this as part of the core.
In the near future there will be a Slot class that is meant to be an
Interface to most of the core types/classes.

I agree with Pit Capitain that the term "slot" is overloaded. Can you
give an example of your Slot class and its usage?

Alexander.
 
G

gabriele renzi

Alexander Staubo ha scritto:
By the usual nomenclature this is an adapter framework -- why not call a
spade a spade? :)

Looks elegantly implemented, though. Ruby definitely needs something
like this as part of the core.

Id did not took the time to check this.. but I proposed something like
this, look out ar rcrchive for "unified conversion framework" :)
 
C

Chad Fowler

Benny is happy to announce his first published piece of software:
"FaceToFace" available as gem.

Congrats on being the author of gem #200 (not counting multiple
versions of the same gem)!

Gem #100 (genx4r - http://genx4r.rubyforge.org/) was released on Oct.
1 by Garrett Rooney.

For those interested, Jim Weirich has an RSS feed that lets you keep
up with gems as they are released:
http://onestepback.org/gemwatch.rss

--

Chad Fowler
http://chadfowler.com
http://rubycentral.org
http://rubygarden.org
http://rubygems.rubyforge.org (over 100,000 gems served!)
 
B

benny

Pit said:
Very nice. One question: how is the return value of the conversion code
used?

well you can see it in the examples: it depends on how you register your
conversion method. the last term in the block is returned. it definitely
makes sense to always return the modified object/result of conversion, but
thats not forced by FaceToFace.


here the modified object is returned (as in myarray << "entry")
perhaps I should talk more about that in the documentation

I think the name "Slot" could be misleading. (See previous discussions
about the term "slot" in this mailing list.) Or are you planning to nest
the name "Slot" in a namespace as in "FaceToFace::Slot"?
yes, I wanted to nest it as FaceToFace::Slot but my english is not the best.
so perhaps you have a proposal for a better name.

I wanted to describe something like a transistion between two worlds. The
object falls into a hole and is suddenly in a world between two worlds,
then it falls through the exit hole and its in another world (the target
world).

Regards,
benny

--
---------------------------------------------------------------------------------------------------
Don't crash when a filter changes the subject of a message which results
in the attempt to remove it from the tree of subject threading messages
failing and the detached child looking for a new parent finding the old
parent as the new parent, which in turn results in the child being deleted
with the old (and new) parent, which is not a good idea, since it is
still referenced.

(Till Adams commit on kdepim/kmail/kmheaders.cpp in HEAD, 6. Jan. 2005)
 
B

benny

Alexander said:
By the usual nomenclature this is an adapter framework -- why not call a
spade a spade? :)
thanks for the info: I didn't knew that ( being musicologist ).
so a will rewrite the gems-description
Looks elegantly implemented, though. Ruby definitely needs something
like this as part of the core.
thank you. perhaps we can implement a gem-like central register of
conversion libs using FaceToFace and this way autmagically install a
required conversion lib, if the method is used but the conversion method is
not there (comparable to require_gem).
I agree with Pit Capitain that the term "slot" is overloaded. Can you
give an example of your Slot class and its usage?

Alexander.
If you hava an idea about a better name. please let me know.

well, it will be some magic behind the scenes. you register the conversion
methods between the "slot" and other classes as usual (but using other
registering methods) and then you convert for example between class A and B
without having registered any direct conversion between them

t = Slot.new( slot_name, struct)
t.register_slot_from( A ) do |a, slot|
.....
end

t.register_slot_to( B ) do |b, slot|
.....
end

a.to! ( B ) #=> searching for direct conversion methods, if not there
searching for common "slots" and convert via the first common slot

or

a.to( B, slot_name) #=> explicitely convert via slot "slot_name"


--
---------------------------------------------------------------------------------------------------
Don't crash when a filter changes the subject of a message which results
in the attempt to remove it from the tree of subject threading messages
failing and the detached child looking for a new parent finding the old
parent as the new parent, which in turn results in the child being deleted
with the old (and new) parent, which is not a good idea, since it is
still referenced.

(Till Adams commit on kdepim/kmail/kmheaders.cpp in HEAD, 6. Jan. 2005)
 
B

benny

gabriele said:
Alexander Staubo ha scritto:

Id did not took the time to check this.. but I proposed something like
this, look out ar rcrchive for "unified conversion framework" :)

I quickly checked it and there a lots of similarities. I will dig into it
later on and we should stay in contact.

benny

--
---------------------------------------------------------------------------------------------------
Don't crash when a filter changes the subject of a message which results
in the attempt to remove it from the tree of subject threading messages
failing and the detached child looking for a new parent finding the old
parent as the new parent, which in turn results in the child being deleted
with the old (and new) parent, which is not a good idea, since it is
still referenced.

(Till Adams commit on kdepim/kmail/kmheaders.cpp in HEAD, 6. Jan. 2005)
 
P

Pit Capitain

benny said:
yes, I wanted to nest it as FaceToFace::Slot but my english is not the best.
so perhaps you have a proposal for a better name.

I wanted to describe something like a transistion between two worlds. The
object falls into a hole and is suddenly in a world between two worlds,
then it falls through the exit hole and its in another world (the target
world).

I'm no native English speaker, too, so I think I'm no big help here, but what
about "Gateway"?

Regards,
Pit
 
B

benny

Pit said:
I'm no native English speaker, too, so I think I'm no big help here, but
what about "Gateway"?

well I think that "Gateway" is misleading. It reminds me of network related
things.

regards,
benny
 
G

George Ogata

benny said:
Benny is happy to announce his first published piece of software:
"FaceToFace" available as gem.


Dear list,

I hope this is useful for someone and I am curious what you think about it.

The code itself is no big deal and always open for improvements (as my
english is).

= Overview

FaceToFace aims to standardize the conversion and messaging
between classes and objects.

You may think of it as syntactic sugar and as duck-typing taken to
the next level (imagine two ducks face to face, none of them being a real
duck).

Up to now we had to remember each method that converts to a
certain class, e.g. 'to_i' converts to Integer, 'to_s' converts to String
etc.

With FaceToFace you only have to remember one method and
you need to know the class to convert to, e.g.
5.to(String ) #=> "5"
"6".to( Integer ) #=> 6

That way you could double-ducktype, i.e. you may not care
about the class of any object you convert to or from, e.g.
def double_duck_me( duck1, duck2 )
duck1.to( duck2.class_name )
end

Instead of using to() you could also use from() to access the result of a
conversion, e.g.
Array.from( "test" ) #=> ["test"]
String.from( 4 ) #=> "4"

[etc.]

Have you seen http://rcrchive.net/rcr/show/280 ? There might be ideas
for you in there.
 
L

Luke Graham

Ive written a similar thing in C++, and for implied conversions I had a
cost, so that the least-lossy path could be followed. Not sure if you
want to do something like that too, I wasnt totally convinced it was
the best way to do it. Counting nodes is the obvious alternative and
takes no work from the user.



Have you seen http://rcrchive.net/rcr/show/280 ? There might be ideas
for you in there.
gabriele renzi pointed me to that one. Seems like we had lot of similar
ideas. I will dig deeper into it when I'm no longer ill and can think
better than now. :)

benny
 
B

benny

Hi Luke,

Luke said:
Ive written a similar thing in C++, and for implied conversions I had a
cost, so that the least-lossy path could be followed. Not sure if you
want to do something like that too, I wasnt totally convinced it was
the best way to do it. Counting nodes is the obvious alternative and
takes no work from the user.
Although I am pretty sure that you were refering to data loss, I first
answer a similar question if you don't mind :).

== concerning performance loss:

Well, implied conversions for me is not a performance, but kind of
"convenience feature". There probably wouldn't be a definite way to
automatically find the fastest conversion-path. That's why I decided to
allow either explicit conversion
myobj.to( YourObj, slotname)
where the user nows what he does or forced implizit conversion
myobj.to!( YourObj )
where the user wants the conversion to be done regardless of perfomance.

The second option easily allows prototyping and latter on you may gain your
performance back by including a direct conversion lib between MyObj and
YourObj or by writing some of your own.

== concerning data loss:

The least lossy path should always be the direct conversion and IMHO every
user using implicit conversion has to make sure that the result of the
conversion is what he expected.

Ok, concider we have "magical" criterias to determine the least lossy
conversion path for him and he does an upgrade of some libs (and with that
maybe a new / other conversion path is chosen).

How can he then make sure that the data he relied on is still in the result?

Therefor if he explicitely chooses the conversion "Slot", he can be sure,
that later added slots won't affect the results.

On the other hand if used the "dangerous" to! mode for prototyping, in the
final overhaul he may simply define a direct conversion which itself refers
to a defined implicit conversion.

Anyway I concider implicit conversion to be a "nice to have" which might be
useful for conversions between simple or similar classes but you can't rely
on it when it comes to complexity.

I would like to contact you, if I'm gonna implement the implicit conversion.
BTW did you use some interconnecting classes/objects for the implicit
conversion and how did you call them (several people pointed out, that the
name "Slot" is misleading, but I have no better name so far).

Regards,
benny
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,169
Messages
2,570,915
Members
47,456
Latest member
JavierWalp

Latest Threads

Top