Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

« Newer Snippets
Older Snippets »
Showing 1-4 of 4 total  RSS 

[ruby] plugin structure

plugin structure sorta thing. Use inherited to concatenate all plugins to a library in a Plugins constant in said library.

class Library
  Plugins = []
  
  def initialize#(...)
    Plugins.each do |plugin|
      # Here you can run a certain class method or grab some data from each class
    end
  end
  
  # ...
end


class LibraryPlugin
  # ...
  
  def self.inherited(sub); Library::Plugins << sub; end
end


class LibraryFooer < LibraryPlugin
  
end
class LibraryBarer < LibraryPlugin
  
end


Library::Plugins.inspect #=> [LibraryFooer, LibraryBarer]

Library interface dialect

REBOL [
    Title:  "Library Interface Dialect"
    File:   %lib-dialect.r
    Author: "Gregg Irwin"
    Purpose: {
        Allow for a more concise way to define library routine 
        interfaces.
    }
]

lib-dialect-ctx: context [
;     lib-ctx: make object! [file: lib: none free: does [free lib]]
;     lib-spec: none

    lib: none
    def-rtn-type: none

    name-mods: copy []
    mod-name: func [name] [do join name-mods name]

    ; dump/trace option to show generated code?

    ;has-rtn-type?: does [all [rtn-type  'none <> rtn-type]]
    ; lib is a global word reference in this func.
    make-dll-func: func [reb-name spec rtn-type name] [
        spec: copy any [spec []]
        if all [rtn-type  'none <> rtn-type] [
            append spec compose/deep [return: [(rtn-type)]]
        ]
        ;print ['make-dll-func reb-name mold spec rtn-type mold  mod-name any [name  form reb-name]]
        set reb-name make routine! spec lib  mod-name any [name  form reb-name]
    ]

    data-type: [
        'none | 'char | 'short | 'long | 'integer! | 'string! | 'decimal!
        ; TBD add struct support ?
    ]

    func-decl: [
        (spec: name: none  rtn-type: def-rtn-type)
        set reb-name word!          ;(print reb-name)
        any [
              [set spec block!]     ;(print mold spec)
            | [opt ['returns | 'as] set rtn-type data-type]  ;(print rtn-type)
            | [opt 'calls set name string!]    ;(print name)
        ]
        (make-dll-func reb-name spec rtn-type name)
    ]

    ; You can use this multiple times, e.g. grouping functions by return
    ; type and using it before each group.
    set-def-rtn-type: [
        opt 'set ['def-rtn-type | 'default-return-type]
        set def-rtn-type data-type
    ]

    rules: [
        ['lib | 'library] set file file! (lib: load/library file) ;append lib-spec compose [file: (file)]
        opt [
            ['modify-import-names | 'mod-imports] set name-mods block!
        ]
        any [set-def-rtn-type | func-decl]
    ]

    set 'make-routines func [spec [any-block!]] [
        clear name-mods
        parse spec rules
    ]

;     set 'make-library-interface func [spec] [
;         lib-spec: copy []
;         clear name-mods
;         parse spec rules
;     ]

]

financial functions

REBOL [
   Title:   "Financial Library"
   Date:    17-Apr-2002
   Name:    'fin
   Version: 0.0.2
   File:    %fin.r
   ;Home:    http://www.pointillistic.com/
   Author:  "Gregg Irwin"
   Email:   gregg@pointillistic.com
   ;Owner:   "Pointillistic Software"
   ;Rights:  "Copyright © Pointillistic Software 2002. All Rights Reserved."
   ;Tabs:    4
   ;Need:    0.1.4
   ;Language: 'English
   ;Charset:  'ANSI
   ;Category: [script 1]
   Purpose: {Financial module for standard library.}

   Comment: {Prototype stage.}

   History: [
      0.0.1 [13-Mar-2002 "First whack" "Gregg"]
      0.0.2 [17-Apr-2002 {Added NPV and a functional, if ugly, IRR.
      BRACKET-FN supports IRR.} "Gregg"]
   ]

   Example: {do %fin.r}
]

fin: make lib-kernel [

    ; Future Value
    fv: func [
        {Computes future value based on present value.}
        value   [number! money!] "Present value"
        rate    [number!] "Interest Rate"
        periods [number!] "Number of time periods"
    ][
        1 + rate ** periods * value
    ]
    ;lib/fin/fv 1000 .1 12
    ;lib/fin/fv 1000 .1 24
    ;lib/fin/fv 1000 .1 36


    ; Compound Interest
    interest: func [
        {Computes accumulated compound interest.}
        value   [number! money!] "Present value"
        rate    [number!] "Interest Rate"
        periods [number!] "Number of time periods"
    ][
        1 + rate ** periods - 1 * value
    ]
    ;lib/fin/interest 1000 .1 12
    ;lib/fin/interest 1000 .1 24
    ;lib/fin/interest 1000 .1 36


    ; Interest Rate
    rate: func [
        {Computes interest rate for a given future value.}
        value        [number! money!] "Present value"
        future-value [number! money!] "Future value"
        periods      [number!] "Number of time periods"
    ][
        future-value / value ** (1 / periods) - 1
    ]
    ;lib/fin/rate 1000 future-value 1000 .1 12 12
    ;lib/fin/rate 1000 future-value 1000 .1 24 24
    ;lib/fin/rate 1000 future-value 1000 .1 36 36


    ; Present Value
    pv: func [
        {Computes present value based on future value.}
        value   [number! money!] "Future value"
        rate    [number!] "Interest Rate"
        periods [number!] "Number of time periods"
    ][
        1 + rate ** (negate periods) * value
        ; - or -
        ;value / (1 + rate ** periods)
    ]
    ;lib/fin/pv future-value 1000 .1 12 .1 12
    ;lib/fin/pv future-value 1000 .1 24 .1 24
    ;lib/fin/pv future-value 1000 .1 36 .1 36

    npv: func [
        {Computes net present value based on future cash flow values
        using continuous discounting.}
        values  [any-block!] "Cash flow values"
        rate    [number!] "Interest Rate"
        /local result
    ][
        result: $0.0
        repeat i length? values [
            result: result + pv values/:i rate i
        ]
        result
    ]
    ;lib/fin/npv [1000 2000 3000] .1
    ;lib/fin/npv [-10000, 3000, 4200, 6800] .1

    ;[-$70'000 $12'000 $15'000 $18'000 $21'000 $26'000]

    ; Time Periods
    nper: func [
        {Computes the number of time periods from the present value
        to a given future value.}
        value        [number! money!] "Present value"
        future-value [number! money!] "Future value"
        rate         [number!] "Interest Rate"
    ][
        ; 2 versions. Both work.
        (log-e (future-value / value)) / (log-e (rate + 1))
        ;divide log-e divide future-value value  log-e add rate 1
    ]
    ;lib/fin/nper 1000 future-value 1000 .1 12 .1
    ;lib/fin/nper 1000 future-value 1000 .1 24 .1
    ;lib/fin/nper 1000 future-value 1000 .1 36 .1

    irr: func [
        {Computes the internal rate of return based on future cash flow values.
        The internal rate of return of a cash flow is the interest rate that
        makes the present value of a cash flow equal to zero. THIS IS A QUICKLY
        HACKED VERSION AND NEEDS TO BE CLEANED UP! HERE FOR TESTING.}
        values  [any-block!] "Cash flow values"
        /guess
            guess-val
        /local rates rate npv-result result
    ][
        tries: 50
        ACCURACY: $.000001
        range: none
        rtb: dx: x-mid: 0.0
        f-mid: $0

        if not guess [guess-val: .2]

        if range: bracket-fn :npv values 0 guess-val [
            either ((npv values range/1) < $0) [
                rtb: range/1
                dx:  range/2 - range/1
            ][
                rtb: range/2
                dx:  range/1 - range/2
            ]
            loop tries [
            	dx: dx * 0.5
            	x-mid: rtb + dx
            	f-mid: npv values x-mid
            	if (f-mid <= $0) [rtb: x-mid]
            	if any [
                    (abs f-mid < ACCURACY)
                    (abs dx < second ACCURACY)
                ] [return x-mid]
            ]
            return none
        ]
    ]

    bracket-fn: func [
        {Adapted from Numerical Recipes. Given a user supplied function and a
        given 'guess' range (x1 to x2) it expands the range geometrically until
        a root is bracketed by the returned values x1 and x2, in which case
        the range is returned as a block of those two values. If it doesn't
        succeed after 50 tries, it returns false. This was built to support
        IRR so it's designed to call NPV, which takes one arg. It should be
        generalized.}
        fn arg x1 x2
        /local factor tries f1 f2
    ][
        tries: 50
        factor: 1.6
        f1: fn arg x1
        f2: fn arg x2
        loop tries [
            ; We have to use SECOND on f2 because it's a money! value
            ; and the numeric component is returned by SECOND.
            if negative? multiply f1 second f2 [
                return reduce [x1 x2]
            ]
            either (abs f1) < (abs f2) [
                x1: x1 + (factor * (x1 - x2))
                f1: fn arg x1
            ][
                x2: x2 + (factor * (x2 - x1))
                f2: fn arg x2
            ]
        ]
        false
    ]
    ;bracket-fn get in lib/fin 'npv values 0 .2
    ;values: [-$70'000 $12'000 $15'000 $18'000 $21'000 $26'000]
    ;lib/fin/irr values
    ;lib/fin/irr copy/part values 5
    ;lib/fin/irr copy/part values 3
    ;lib/fin/irr/guess copy/part values 3 -.1
    ;values: [-10 1.8 1.8 1.8 1.8 1.8 1.8 1.8 2.8]
    ;lib/fin/irr values
    ;values: [0 -1073 -1459 -1364 -1247 -1110 31789]
    ;lib/fin/irr values

;     irr: func [
;         {Computes the internal rate of return based on future cash flow values.
;         The internal rate of return of a cash flow is the interest rate that
;         makes the present value of a cash flow equal to zero. THIS IS A QUICKLY
;         HACKED VERSION AND NEEDS TO BE CLEANED UP! HERE FOR TESTING.}
;         values  [any-block!] "Cash flow values"
;         /guess
;             guess-val
;         /local rates rate npv-result result
;     ][
;         ACCURACY: $.000001
;         tries: 50
;         range: none
;         rtb: dx: x-mid: 0.0
;         f-mid: $0
;         if not guess [guess-val: .2]
;         if range: bracket-fn :npv values 0 guess-val [
;             f: npv values range/1
;             either (f < $0) [
;                 rtb: range/1
;                 dx: range/2 - range/1
;             ][
;                 rtb: range/2
;                 dx: range/1 - range/2
;             ]
;             loop tries [
;             	dx: dx * 0.5
;             	x-mid: rtb + dx
;             	f-mid: npv values x-mid
;             	if (f-mid <= $0) [rtb: x-mid]
;             	if any [
;                     ((abs f-mid) < ACCURACY)
;                     ((abs dx) < (second ACCURACY))
;                 ] [return x-mid]
;             ]
;             return none
;         ]
;     ]
;
;     bracket-fn: func [
;         {Adapted from Numerical Recipes. Given a user supplied function and a
;         given 'guess' range (x1 to x2) it expands the range geometrically until
;         a root is bracketed by the returned values x1 and x2, in which case
;         the range is returned as a block of those two values. If it doesn't
;         succeed after 50 tries, it returns false. This was built to support
;         IRR so it's designed to call NPV, which takes one arg. It should be
;         generalized.}
;         fn arg x1 x2
;         /local factor tries f1 f2
;     ][
;         tries: 50
;         factor: 1.6
;         f1: fn arg x1
;         f2: fn arg x2
;         loop tries [
;             ; We have to use SECOND on f2 because it's a money! value
;             ; and the numeric component is returned by SECOND.
;             if negative? multiply f1 second f2 [
;                 return reduce [x1 x2]
;             ]
;             either (abs f1) < (abs f2) [
;                 x1: x1 + (factor * (x1 - x2))
;                 f1: fn arg x1
;             ][
;                 x2: x2 + (factor * (x2 - x1))
;                 f2: fn arg x2
;             ]
;         ]
;         false
;     ]

]

Java-Like Javascript Library Container //Javascript Object

//+ Jonas Raoni Soares Silva
//@ http://jsfromhell.com

libraryControl = {
	baseURI: '',
	packs: {},

	register: function( pack ){
		for( var _, m, p = this.packs, pack = ( m = pack.split( '.' ) ).pop(); _ = m.shift(); p = p[_] || ( p[_]={} ) );
		( p['%files%'] || ( p['%files%'] = {} ) )[pack] = {included:false,loaded:false};
	},

	findPackage: function( pack ){
		for( var m, p = this.packs, pack = ( m = pack.split( '.' ) ).pop(); m.length && ( p = p[ m.shift() ] ); );
		return !m.length && (p=p['%files%']) ? p[pack] : null;
	},

	isIncluded: function( pack ){
		with( {x:this.findPackage( pack )} ) return x && x.included;
	},

	isLoaded: function( pack ){
		with( {x:this.findPackage( pack )} ) return x && x.loaded;
	},

	include: function( pack ) {
		var p = this.findPackage( pack ), pack = this.baseURI + pack.split( '.' ).join( '/' ) + '.js';
		if( p ){
			if( !document.body )
				document.write( '<script type="text/javascript" src="'+pack+'"><\/script>' );
			else with( {s: document.createElement( 'script' ) } ){
				s.type = 'text/javascript';
				s.src = pack;
				document.body.appendChild( s );
			}
			return p.included = true;
		}
		return false;
	},

	require: function( pack ) {
		var p = this.findPackage( pack );
  		if( p && !p.included )
			return this.include( pack );
		return false;
	}
}

//libraryControl.register( 'library.test' );
//libraryControl.require( 'library.test' );
//libraryControl.include( 'library.test' );

« Newer Snippets
Older Snippets »
Showing 1-4 of 4 total  RSS