[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

[ANN] shared-0.4.2

ara.t.howard

11/9/2008 7:40:00 PM


NAME
shared.rb

DESCRIPTION
super simple super power sharing of instance and class level code

INSTALL
gem install shared

URIS
http://rubyforge.org/projects/cod...
http://codeforpeople.com...

HISTORY
0.4.2
initial version

SAMPLES

<========< samples/a.rb >========>

~ > cat samples/a.rb

# shared.rb is a very simple and very powerful method of sharing
code between
# classes.
#
require 'shared'

shared(:code) do
def classname() self.class.name end
end

class Foo
include shared(:code)
end

class Bar
include shared(:code)
end

p Foo.new.classname #=> "Foo"

p Bar.new.classname #=> "Bar"

~ > ruby samples/a.rb

"Foo"
"Bar"


<========< samples/b.rb >========>

~ > cat samples/b.rb

# shared.rb allows natural declaration of both instance and class-
level
# methods - it's more than simple module inclusion
#

require 'shared'

shared('methods') do
def self.class_method() 40 end

def instance_method() 2 end
end

class C
include shared('methods')
end

p(C.class_method + C.new.instance_method) #=> 42


~ > ruby samples/b.rb

42


<========< samples/c.rb >========>

~ > cat samples/c.rb

# shared.rb works equally well with individual objects in
addition to the
# normal class level usage
#

require 'shared'

shared(:meta_tools) do
def singleton_class &block
singleton_class =
class << self
self
end
block ? singleton_class.module_eval(&block) : singleton_class
end
end

a = %w( a b c )

a.extend shared(:meta_tools)

a.singleton_class do
def to_range() first .. last end
end

p a.to_range #=> "a".."c"

~ > ruby samples/c.rb

"a".."c"


<========< samples/d.rb >========>

~ > cat samples/d.rb

# an example use-case for shared.rb is sharing code bewteen
classes that
# require both class level and instance level behaviour to be
shared
#

require 'shared'

shared(:acts_as_named) do
validates_precence_of :name

def to_html() "<blink> #{ name } </blink>" end
end

class Model
def Model.validates_precence_of(*a) end

def name() 'zaphod' end

include shared(:acts_as_named)
end

p Model.new.to_html #=> "<blink> zaphod </blink>"

~ > ruby samples/d.rb

"<blink> zaphod </blink>"


<========< samples/e.rb >========>

~ > cat samples/e.rb

# it's important to note that the shared code is injected into
the reciever
# fresh on each call and, in that way, the effect is rather macro
like
#

require 'shared'

share(:instance_tracker) do
const_set :Instances, []

def self.instances() const_get :Instances end

def self.new *a, &b
obj = super
ensure
instances << obj
end
end

class Foo
include shared(:instance_tracker)
end

class Bar
include shared(:instance_tracker)
end

2.times{ Foo.new }
40.times{ Bar.new }

p(Foo.instances.size + Bar.instances.size)

~ > ruby samples/e.rb

42





enjoy.



a @ http://codeforp...
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama




8 Answers

Joel VanderWerf

11/9/2008 8:47:00 PM

0

ara howard wrote:
>
> NAME
> shared.rb
...
> enjoy.

shared and enjoyed ;)

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Stefan Rusterholz

11/9/2008 9:01:00 PM

0

Ara Howard wrote:
> NAME
> shared.rb
>
> DESCRIPTION
> super simple super power sharing of instance and class level code

Hi Ara

Thanks a lot for sharing another of your fine libraries :)
May I ask why I would introduce the dependency 'shared' instead of using
rubys native code sharing facility that is inheritance and (IMO more
powerful) modules? Where do you see the striking advantages of shared?

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

ara.t.howard

11/9/2008 9:32:00 PM

0


On Nov 9, 2008, at 2:00 PM, Stefan Rusterholz wrote:

> Hi Ara
>
> Thanks a lot for sharing another of your fine libraries :)
> May I ask why I would introduce the dependency 'shared' instead of
> using
> rubys native code sharing facility that is inheritance and (IMO more
> powerful) modules? Where do you see the striking advantages of shared?
>
> Regards
> Stefan


well, for starters it *is* based on modules ;-) the striking
advantage is, as a for instance, that you can do this in rails

in lib/shared.rb

shared :before_filters do
before_filter :foo
before_filter :bar

def foo() end
def bar() end
end

in app/controllers/foo_controller.rb

class Foo < ApplicationController
include shared(:before_filters)
end

in app/controllers/bar/controller.rb

class Bar < ApplicationController
include shared(:before_filters)
end


this is absolutely not easily done with modules. shared.rb has all
the advantages of ruby module sharing *plus* the simplicity of
completely POLS class level method sharing.

another example, which is not easily done using modules

in lib/shared.rb

shared :home_controller do
before_filter :must_have_user

def index
render 'shared/home'
end

protected
def must_have_user() end
end

in app/controllers/teacher/home_controller.rb

class Teacher::HomeController < ApplicationController
include shared(:home_controller)
end

in app/controllers/student/home_controller.rb

class Student::HomeController < ApplicationController
include shared(:home_controller)
end



so, in that example, we can directly setup a public method (index
action) and protected method, and call a class method. try doing that
with modules and you'll see that it's rather un-natural. the call to
before_filter, for instance, cannot simply be wrapped with the normal
'ClassMethods' hack, but must actually be deferred because it only
*exists* in the target classes - aka it doesn't exist in the mixin but
only exists in the mixxee (controllers) making it a chicken-and-egg
issue when code sharing is desired.

shared let's you factor out chunks of code *exactly* as you would have
typed them before and then, later, to inject them into classes or
module or objects *exactly as if you'd entered the code there*

make sense?

cheers.
a @ http://codeforp...
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama




ara.t.howard

11/9/2008 9:35:00 PM

0


On Nov 9, 2008, at 2:00 PM, Stefan Rusterholz wrote:

> Hi Ara
>
> Thanks a lot for sharing another of your fine libraries :)
> May I ask why I would introduce the dependency 'shared' instead of
> using
> rubys native code sharing facility that is inheritance and (IMO more
> powerful) modules? Where do you see the striking advantages of shared?
>
> Regards
> Stefan



one last thing - shared.rb is only 44 lines of code so i really don't
expect you to introduce a dependancy, rather i expect you to steal it
and drop it into your project's lib dir and be done with it. it's
small enough to simply cut and paste into any existing project as well.

if you want to depend on it, however, the gem makes it easy.

cheers.

a @ http://codeforp...
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama




Stefan Rusterholz

11/9/2008 10:34:00 PM

0

Ara Howard wrote:
> shared :before_filters do
> before_filter :foo
> before_filter :bar
>
> def foo() end
> def bar() end
> end
>
> in app/controllers/foo_controller.rb
>
> class Foo < ApplicationController
> include shared(:before_filters)
> end
>
> in app/controllers/bar/controller.rb
>
> class Bar < ApplicationController
> include shared(:before_filters)
> end

module SharedBeforeFilters
def self.included(by)
by.before_filter :foo
by.before_filter :bar
end

def foo(); end
def bar(); end
end

in app/controllers/foo_controller.rb
class Foo < ApplicationController
include SharedBeforeFilters
end

in app/controllers/bar_controller.rb
class Bar < ApplicationController
include SharedBeforeFilters
end

> this is absolutely not easily done with modules.

I don't see the problem here.

shared.rb has all
> the advantages of ruby module sharing *plus* the simplicity of
> completely POLS class level method sharing.
>
> another example, which is not easily done using modules
>
> in lib/shared.rb
>
> shared :home_controller do
> before_filter :must_have_user
>
> def index
> render 'shared/home'
> end
>
> protected
> def must_have_user() end
> end
>
> in app/controllers/teacher/home_controller.rb
>
> class Teacher::HomeController < ApplicationController
> include shared(:home_controller)
> end
>
> in app/controllers/student/home_controller.rb
>
> class Student::HomeController < ApplicationController
> include shared(:home_controller)
> end
>
> so, in that example, we can directly setup a public method (index
> action) and protected method, and call a class method. try doing that
> with modules and you'll see that it's rather un-natural.

module HomeController
def self.included(by)
by.before_filter :must_have_user
end

def index
render 'shared/home'
end

protected
def must_have_user() end
end

in app/controllers/teacher/home_controller.rb
class Teacher::HomeController < ApplicationController
include HomeController
end

in app/controllers/student/home_controller.rb
class Student::HomeController < ApplicationController
include HomeController
end

Again, I don't see the issue. But maybe I miss the obvious or something
:-/

> make sense?

Not sure yet. But thanks for the explanations!

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

ara.t.howard

11/9/2008 11:35:00 PM

0


On Nov 9, 2008, at 3:33 PM, Stefan Rusterholz wrote:

> Again, I don't see the issue. But maybe I miss the obvious or
> something

what you are missing is that you are good @ ruby ;-)

seriously though, it really does get messy with class instance vars
and especially @@class vars. shared just let's you forget about it.
mostly it's motivated by me getting sick of writing 'included' hooks
and 'class << other' - that's it.

cheers.

a @ http://codeforp...
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama




Stefan Rusterholz

11/9/2008 11:38:00 PM

0

Ara Howard wrote:
> On Nov 9, 2008, at 3:33 PM, Stefan Rusterholz wrote:
>
>> Again, I don't see the issue. But maybe I miss the obvious or
>> something
>
> what you are missing is that you are good @ ruby ;-)
>
> seriously though, it really does get messy with class instance vars
> and especially @@class vars. shared just let's you forget about it.
> mostly it's motivated by me getting sick of writing 'included' hooks
> and 'class << other' - that's it.
>
> cheers.
>
> a @ http://codeforp...

Ok. Then one request:
Add the global methods to Kernel instead of Object (as they are, as I
understand them, quasi-global methods and not instance methods) and make
them private (to not disable method_missing for them).

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

ara.t.howard

11/10/2008 12:40:00 AM

0


On Nov 9, 2008, at 4:37 PM, Stefan Rusterholz wrote:

> Ok. Then one request:
> Add the global methods to Kernel instead of Object (as they are, as I
> understand them, quasi-global methods and not instance methods) and
> make
> them private (to not disable method_missing for them).

both good ideas. done.

HISTORY 0.4.3
- added version info
- move methods from Object to Kernel and made them private (thx
Stefan Rusterholz)

just pushed to rubyforge.

cheers.

a @ http://codeforp...
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama