[ANN] shared-0.4.2

A

ara howard

NAME
shared.rb

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

INSTALL
gem install shared

URIS
http://rubyforge.org/projects/codeforpeople
http://codeforpeople.com/lib/ruby/

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://codeforpeople.com/
 
S

Stefan Rusterholz

Ara said:
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
 
A

ara.t.howard

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://codeforpeople.com/
 
A

ara.t.howard

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://codeforpeople.com/
 
S

Stefan Rusterholz

Ara said:
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
 
A

ara.t.howard

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://codeforpeople.com/
 
S

Stefan Rusterholz

Ara said:
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://codeforpeople.com/

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
 
A

ara.t.howard

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://codeforpeople.com/
 

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

Similar Threads

[ANN] terminator-0.4.2 0
[ANN] state-0.4.2 0
[ANN] tagz-5.0.0 43
[ANN] prototype-1.0.0 0
[ANN] tagz-4.6.0 1
[ANN] main-4.0.0 (for avdi) 0
[ANN] tagz-4.2.0 - giraffe slayer 9
ANN main-4.4.0 0

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top