[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Whats the ruby way of associating metadata with a function

Keith Chapman

11/13/2007 8:44:00 AM

Hi All,

I've pretty new to ruby and still getting to know how ruby works. I want
to associate some metadata to a function. I saw a similar post down this
line but didn't get the real answer.

In javascript I'm used to associating metadata with a function as
follows.

foo.bar = "foobar";
function foo(){
}

Whats the normal ruby practice to do this kind of a thing. Whats the
ruby way of doing this.

Your help is very much appreciated.

Thanks,
Keith.
--
Posted via http://www.ruby-....

7 Answers

Robert Klemme

11/13/2007 9:13:00 AM

0

2007/11/13, Keith Chapman <keithgchapman@gmail.com>:
> Hi All,
>
> I've pretty new to ruby and still getting to know how ruby works. I want
> to associate some metadata to a function. I saw a similar post down this
> line but didn't get the real answer.
>
> In javascript I'm used to associating metadata with a function as
> follows.
>
> foo.bar = "foobar";
> function foo(){
> }
>
> Whats the normal ruby practice to do this kind of a thing. Whats the
> ruby way of doing this.

You typically use a class instance variable. For example:

class Foo
def self.meta() @method_meta ||= {} end

def bar() 1 end

meta[:bar]=567
puts meta[:bar], meta[:foo]
end

puts Foo.meta[:bar], Foo.meta[:foo]

Kind regards

robert

--
use.inject do |as, often| as.you_can - without end

furtive.clown

11/13/2007 9:42:00 AM

0

On Nov 13, 3:43 am, Keith Chapman <keithgchap...@gmail.com> wrote:
>
> In javascript I'm used to associating metadata with a function as
> follows.
>
> foo.bar = "foobar";
> function foo(){
>
> }
>
> Whats the normal ruby practice to do this kind of a thing. Whats the
> ruby way of doing this.

Three options come to mind:

==================================================
#1 : add accessors to the singleton of a lambda

foo = lambda {
puts "foo!!"
}

class << foo
attr_accessor :bar
end

foo.bar = "foobar"

foo.call # => "foo!!"
puts foo.bar # => "foobar"

==================================================
#2 : add a hash to the singleton of a lambda

foo = lambda {
puts "foo!!"
}

class << foo
def meta
@meta ||= Hash.new
end
end

foo.meta[:bar] = "foobar"

foo.call # => "foo!!"
puts foo.meta[:bar] # => "foobar"

==================================================
#3 : add a method to the singleton of an OpenStruct

require 'ostruct'

foo = OpenStruct.new

class << foo
def call
puts "foo!!"
end
end

foo.bar = "foobar"

foo.call # => "foo!!"
puts foo.bar # => "foobar"

All other things being equal, I would be inclined toward #3.


Keith Chapman

11/13/2007 9:44:00 AM

0

Hi Robert,

If I extend my question a bit further

foo.bar = "bar";
function foo(){
}

foobar.bar = "foobar";
function foobar(){
}

How can I support something like this?

Thanks,
Keith.


Robert Klemme wrote:
> 2007/11/13, Keith Chapman <keithgchapman@gmail.com>:
>> function foo(){
>> }
>>
>> Whats the normal ruby practice to do this kind of a thing. Whats the
>> ruby way of doing this.
>
> You typically use a class instance variable. For example:
>
> class Foo
> def self.meta() @method_meta ||= {} end
>
> def bar() 1 end
>
> meta[:bar]=567
> puts meta[:bar], meta[:foo]
> end
>
> puts Foo.meta[:bar], Foo.meta[:foo]
>
> Kind regards
>
> robert

--
Posted via http://www.ruby-....

furtive.clown

11/13/2007 10:18:00 AM

0

On Nov 13, 4:43 am, Keith Chapman <keithgchap...@gmail.com> wrote:
>
> foo.bar = "bar";
> function foo(){
>
> }
>
> foobar.bar = "foobar";
> function foobar(){
>
> }
>
> How can I support something like this?

require 'ostruct'

class FunctionWithMetaData < OpenStruct
def initialize(&block)
super
@func = block
end

def call(*args)
@func.call(*args)
end
end

foo = FunctionWithMetaData.new { |x|
x*10
}

foo.bar = "qux"
foo.baz = "bop"

puts foo.bar # => "qux"
puts foo.baz # => "bop"
puts foo.call(3) # => 30

fred = FunctionWithMetaData.new {
"fred function"
}

fred.arms = 2
fred.fingers = 10

puts fred.arms # => 2
puts fred.fingers # => 10
puts fred.call # => "fred function"

Robert Klemme

11/13/2007 10:27:00 AM

0

2007/11/13, Keith Chapman <keithgchapman@gmail.com>:
> Hi Robert,
>
> If I extend my question a bit further
>
> foo.bar = "bar";
> function foo(){
> }
>
> foobar.bar = "foobar";
> function foobar(){
> }
>
> How can I support something like this?

The example is kind of artificial. Can you disclose more detail on
what you are trying to achieve? There are millions of ways to answer
your question and meta data for methods might not even be the best
solution.

Kind regards

robert

--
use.inject do |as, often| as.you_can - without end

Keith Chapman

11/15/2007 6:31:00 AM

0

Hi Robert and others,

We are trying to define a way of writing web services in ruby (Code
First approach). And we expect to keep it as simple as possible. In
order to do this we need to define some metadata that we can use to
generate a pleasant WSDL. This metadata may include things like
documentation and details about input and output Types. Note that ruby
is a Dynamic language whereas xml schema is not. And although a
parameter taken into a function could be of anyType in most cases it
operates on it assuming its of a certain type. And getting this
information into the WSDL matters in that case.

Assume that I have a function as follows,

def foo(bar, foobar)

end

I need to get the information on the types expected by this function
across to the WSDL. I basically need a way to say that bar is a String
and foobar is an integer. This is where the matadata that I'm talking
about comes into play.

It will be nice if the Ruby community can help us figure out a nice
rubish way of doing this. The most important thing is that I want this
all to fit in with ruby people so this should look rubish as much as
possible.

Once we get this done we have more cool stuff in mind...

Thanks,
Keith.



Robert Klemme wrote:
> 2007/11/13, Keith Chapman <keithgchapman@gmail.com>:
>> }
>>
>> How can I support something like this?
>
> The example is kind of artificial. Can you disclose more detail on
> what you are trying to achieve? There are millions of ways to answer
> your question and meta data for methods might not even be the best
> solution.
>
> Kind regards
>
> robert

--
Posted via http://www.ruby-....

Robert Klemme

11/15/2007 3:13:00 PM

0

2007/11/15, Keith Chapman <keithgchapman@gmail.com>:
> Hi Robert and others,
>
> We are trying to define a way of writing web services in ruby (Code
> First approach). And we expect to keep it as simple as possible. In
> order to do this we need to define some metadata that we can use to
> generate a pleasant WSDL. This metadata may include things like
> documentation and details about input and output Types. Note that ruby
> is a Dynamic language whereas xml schema is not. And although a
> parameter taken into a function could be of anyType in most cases it
> operates on it assuming its of a certain type. And getting this
> information into the WSDL matters in that case.
>
> Assume that I have a function as follows,
>
> def foo(bar, foobar)
>
> end
>
> I need to get the information on the types expected by this function
> across to the WSDL. I basically need a way to say that bar is a String
> and foobar is an integer. This is where the matadata that I'm talking
> about comes into play.
>
> It will be nice if the Ruby community can help us figure out a nice
> rubish way of doing this. The most important thing is that I want this
> all to fit in with ruby people so this should look rubish as much as
> possible.

Well, then it sounds as if you need structured data for a method.
Extending my last proposed solution a bit you could do this:

16:08:14 /cygdrive/c$ cat meta.rb
require 'ostruct'

class Foo
def self.meta()
@method_meta ||= Hash.new {|h,k| h[k]=OpenStruct.new}
end

def bar() 1 end

meta[:bar].length=567
meta[:bar].return_type=Integer
end

puts Foo.meta[:bar]
16:08:48 /cygdrive/c$ ruby meta.rb
#<OpenStruct return_type=Integer, length=567>
16:08:50 /cygdrive/c$

Of course you can use a Hash instead of the OpenStruct - but that's
probably rather a matter of taste. If you need automatic discovery of
meta data set I'd probably rather use a Hash - if you know which meta
data you expect I'd probably use an OpenStruct or a Struct.

Cheers

robert

--
use.inject do |as, often| as.you_can - without end