Project

tsundere

0.0
No commit activity in last 3 years
No release in over 3 years
Any given object can implement the tsundere interface. Once implemented, a tsundere object will behave differently based upon who is calling it.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 1.2.3
~> 1.8.4
~> 3.12
~> 2.12.0
 Project Readme

~tsun tsun

Provides an interface to allow objects to behave differently based upon who is accessing them. Objects implementing the tsundere class exposes a tsundere_for method that creates a proxy which filters out unwanted access smoothly.

Suppose you have the following:

# Object
class SchoolGirl
	def speak_with words
		...
	end

	def watch_movie_with person
		...
	end 

	def bathe_with person
		...
	end 

	def be_naughty_with person, &block
		yield person, &block
		...
	end

	def ignore
		...
	end
end

...

# Usage
rikka = SchoolGirl.new :chuu2
if person.is_a? Friend
	rikka.speak_with person.words
else
	rikka.ignore person
end
if person.is_a? Friend and person.is_a? Neighbor and person.name =~ /dark flame master/i
	rikka.speak_with person.words
	rikka.bathe_with person
	...
end

The annoying thing is that you need to constantly check for access levels, which makes your code a mess and becomes easily broken with new updates. The tsundere interface provides an access level interface to make thing easier:

# Object
class SchoolGirl
	include Tsundere
	attr_tsundere :speak_with, :as => { :stranger => 1 }
	attr_tsundere :watch_movie_with, :as => { :friend => 2 }
	attr_tsundere :bathe_with, :be_naughty_with :as => { :dark_flame_master => 3 }
	def speak_with words
		...
	end

	def watch_movie_with person
		...
	end 

	def bathe_with person
		...
	end 

	def be_naughty_with person, &block
		yield person, &block
		...
	end

	def ignore
		...
	end
end

...

# Usage
rikka = SchoolGirl.new :chuu2
# if person is a friend, these method will work, if not, this method returns
# a string saying "sorry, this doesn't work"
rikka.tsundere_for(person).speak_with person.words
rikka.tsundere_for(person).watch_movie_with person, 
...

Another Use Case

For when you are on rails, already have written your view partials, your helpers, but now suddenly need to mix in or update your permission system.

# Original code

# Your model
class Invoice < ActiveRecord::Base
	...
end # Invoice

# Some helper you have
module PageHelper
	def generate_tileview_hash invoice
		output = {
			:title => invoice.title ,
			:content => invoice.text ,
			...
		}
	end # generate_tile_hash
end # PageHelper

# Your view
=render "shared/tileview", :tile => generate_tileview_hash(@invoice)

Everything is going fine, when suddenly on Friday afternoon:

## Here, your boss says he needs a permission system so that
# only level 3 (accounting) and up can see the sales prices
# on any given invoice

If you're using cancan, authority, lots of conditions in your views, or what have you, you are screwed. You must now spend the weekend going through your views and modifying all the conditions, handle all the new exceptions, etc.

But with Tsundere, things are easier (but it's not like I built this so things can be easier for you, baka!).

# Your fixed model
class Invoice < ActiveRecord::Base
	attr_tsundere :price, :fail => "Access-denied", :as => { :acounting => 3 }
end # Invoice

# Your view
=render "shared/tileview", :tile => generate_tileview_hash(@invoice.tsundere_for(current_user))

Install

gem install tsundere

Usage

  1. step 1: include the tsundere module into your class
class Something
	include Tsundere
	...
  1. step 2: declare what methods you'd like to be accessible in one of 3 ways:
class Something
	include Tsundere
	attr_tsundere :some_method, :another_method, :as => :admin
	attr_tsundere :fourth_method, :as => :management

admins can access some_method and another_method management can access fourth_method

--

class Something
	include Tsundere
	attr_tsundere :some_method, :another_method, :third_method, :as => {:admin => 5}
	attr_tsundere :fourth_method, :as => {:super_admin => 6}

declared this way, and super_admin can not only access fourth_method, but also all the methods the regular admin can access

--

class Something
	include Tsundere
	attr_tsundere :some_method, :another_method, :third_method, :as => 5
	attr_tsundere :fourth_method, :as => 6

this is the same as the previous version, except no names are specified, but tsundere_for(6) can access fourth_method as well as all the methods that tsundere_for(5) can access

Notes

tsundere_for(duck)

tsundere_for will work as long as duck is either a string, fixnum, symbol, integer, or float. Alternatively, if duck exposes a rank or level method that results in a fixnum, string, symbol, float, etc., this method will still work. If duck is a hash, it must expose the :rank or :level key in order to work If duck is nil, no methods are exposed.

If you don't want to bother with access levels at some point in your application, simple call your original object without tsundere_for

Contributing to tsundere

  • Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
  • Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
  • Fork the project.
  • Start a feature/bugfix branch.
  • Commit and push until you are happy with your contribution.
  • Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
  • Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.

Copyright

Copyright (c) 2012 Thomas Chen. See LICENSE.txt for further details.