module StrongTyping

Constants

VERSION

The version of the strongtyping library

Public Class Methods

expect(*args) click to toggle source
static VALUE strongtyping_expect(int argc, VALUE *argv, VALUE self UNUSED) {
  int i = 0;
  VALUE obj[MAXARGS], mod[MAXARGS];
  VALUE typestr;

  if(!argc)
    return Qnil;

  if(argc % 2)
    rb_raise(rb_eSyntaxError, "expect() requires argument pairs");

#ifndef __GNUC__
  if(argc*2 > MAXARGS*2)
    rb_raise(rb_eSyntaxError, "too many arguments to expect()");
#endif

  for(i = 0; i < argc; i += 2) {
    obj[i/2]     = argv[i];
    mod[(i+1)/2] = argv[i+1];
  }

  if(rb_funcall(obj[0], id_isa, 1, cQueryParams)) {
    rb_funcall(obj[0], rb_intern("<<"), 1, rb_ary_new4(argc/2, mod));
    rb_raise(eArgList, ""); // TODO: Why an empty string? Causes a warning in 1.9.x.
  }
    
  i = check_args(argc / 2, obj, mod);

  if(i < 0)
    return Qnil;

  typestr = rb_funcall(mod[i], id_inspect, 0);

  rb_raise(
    eArgumentTypeError,
    "Expecting %s as argument %d, got %s",
    RSTRING_PTR(typestr), i + 1,
    rb_class2name(rb_funcall(obj[i], id_class, 0))
  );
}
get_arg_types(p1) click to toggle source
static VALUE strongtyping_get_arg_types(VALUE obj UNUSED, VALUE method) {
  VALUE query, ary;
  query = rb_funcall(cQueryParams, rb_intern("new"), 0);
  ary   = rb_ary_new3(2, method, query);
    
  return rb_rescue2(call_method, ary, grab_types, query, eArgList, 0);
}
overload(*args) click to toggle source
static VALUE strongtyping_overload(int argc, VALUE *argv, VALUE self UNUSED) {
  struct RArray *q;
    
  if(argc < 1)
    rb_raise(rb_eArgError, "At least one parameter required");

  Check_Type(argv[0], T_ARRAY);
  q = RARRAY(argv[0]);

  if(RARRAY_LEN(q) && rb_funcall(RARRAY_PTR(q)[0], id_isa, 1, cQueryParams)) {
    rb_funcall(RARRAY_PTR(q)[0], rb_intern("<<"), 1, rb_ary_new4(argc - 1, argv + 1));
    return Qnil;
  }

  if(RARRAY_LEN(q) != (argc - 1))
    return Qnil;

  if(check_args(argc - 1, RARRAY_PTR(q), argv + 1) < 0){
    if(argc == 2)
      rb_yield(*RARRAY_PTR(*argv));
    else
      rb_yield(*argv);
  }

  return Qnil;
}
overload_default(p1) click to toggle source
static VALUE strongtyping_overload_error(VALUE self UNUSED, VALUE args) {
  struct  RArray *q;
  VALUE           classlist;
  const char      *name = 0;
  int             i    = 0;
    
  Check_Type(args, T_ARRAY);
  q = RARRAY(args);
    
  if(RARRAY_LEN(q) && rb_funcall(RARRAY_PTR(q)[0], id_isa, 1, cQueryParams))
    rb_raise(eArgList, "");

  classlist = rb_str_new2("");

  for(i = 0; i < RARRAY_LEN(q); i++) {
    if(i > 0)
      rb_str_cat(classlist, ", ", 2);

    name = rb_class2name(rb_funcall(RARRAY_PTR(q)[i], id_class, 0));
    rb_str_cat(classlist, name, strlen(name));
  }

  rb_raise(
    eOverloadError,
    "No matching template for arguments: [%s]",
    RSTRING_PTR(classlist)
  );
}
overload_error(p1) click to toggle source
static VALUE strongtyping_overload_error(VALUE self UNUSED, VALUE args) {
  struct  RArray *q;
  VALUE           classlist;
  const char      *name = 0;
  int             i    = 0;
    
  Check_Type(args, T_ARRAY);
  q = RARRAY(args);
    
  if(RARRAY_LEN(q) && rb_funcall(RARRAY_PTR(q)[0], id_isa, 1, cQueryParams))
    rb_raise(eArgList, "");

  classlist = rb_str_new2("");

  for(i = 0; i < RARRAY_LEN(q); i++) {
    if(i > 0)
      rb_str_cat(classlist, ", ", 2);

    name = rb_class2name(rb_funcall(RARRAY_PTR(q)[i], id_class, 0));
    rb_str_cat(classlist, name, strlen(name));
  }

  rb_raise(
    eOverloadError,
    "No matching template for arguments: [%s]",
    RSTRING_PTR(classlist)
  );
}
overload_exception(*args) click to toggle source
static VALUE strongtyping_overload_exception(int argc, VALUE *argv, VALUE self UNUSED) {
  struct RArray *q;
    
  if(argc < 1)
    rb_raise(rb_eArgError, "At least one parameters required");

  Check_Type(argv[0], T_ARRAY);
  q = RARRAY(argv[0]);

  if(RARRAY_LEN(q) && (argc - 1) == 0)
    return Qnil;

  if(check_args(argc - 1, RARRAY_PTR(q), argv + 1) < 0)
    rb_yield(argv[0]);

  return Qnil;
}
verify_args_for(p1, p2) click to toggle source
static VALUE strongtyping_verify_args_for(VALUE self, VALUE method, VALUE args) {
  struct RArray *list = NULL;
  struct RArray *t    = NULL;
  struct RArray *a    = NULL;
  int i    = 0;
  VALUE template = strongtyping_get_arg_types(self, method);

  list = RARRAY(template);
  a    = RARRAY(args);

  for(i = 0; i < RARRAY_LEN(list); i++){
    t = RARRAY_PTR(list)[i];

    if(RARRAY_LEN(a) != RARRAY_LEN(t))
      continue;

    if(check_args(RARRAY_LEN(a), RARRAY_PTR(a), RARRAY_PTR(t)) < 0)
      return Qtrue;
  }
    
  return Qfalse;
}