Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Working SyncUpdate implementation

Allow to
- Create
- Update
- Delete
an Net::Whois::Object
(only with password yet)
  • Loading branch information...
commit 4db38214ac9a96b58bda697e89ae96cc741f9b97 1 parent 1f31cce
arhuman authored July 04, 2012

Showing 54 changed files with 1,506 additions and 1,290 deletions. Show diff stats Hide diff stats

  1. 1  Changes
  2. 5  MANIFEST
  3. 3  credentials.sh
  4. 264  lib/Net/Whois/Object.pm
  5. 32  lib/Net/Whois/Object/AsBlock.pm
  6. 32  lib/Net/Whois/Object/AsSet.pm
  7. 50  lib/Net/Whois/Object/AutNum.pm
  8. 43  lib/Net/Whois/Object/Domain.pm
  9. 38  lib/Net/Whois/Object/FilterSet.pm
  10. 43  lib/Net/Whois/Object/Inet6Num.pm
  11. 44  lib/Net/Whois/Object/InetNum.pm
  12. 42  lib/Net/Whois/Object/InetRtr.pm
  13. 8  lib/Net/Whois/Object/Information.pm
  14. 47  lib/Net/Whois/Object/Irt.pm
  15. 32  lib/Net/Whois/Object/KeyCert.pm
  16. 28  lib/Net/Whois/Object/Limerick.pm
  17. 42  lib/Net/Whois/Object/Mntner.pm
  18. 47  lib/Net/Whois/Object/Organisation.pm
  19. 35  lib/Net/Whois/Object/PeeringSet.pm
  20. 30  lib/Net/Whois/Object/Person.pm
  21. 30  lib/Net/Whois/Object/Poem.pm
  22. 26  lib/Net/Whois/Object/PoeticForm.pm
  23. 22  lib/Net/Whois/Object/Response.pm
  24. 36  lib/Net/Whois/Object/Role.pm
  25. 44  lib/Net/Whois/Object/Route.pm
  26. 46  lib/Net/Whois/Object/Route6.pm
  27. 34  lib/Net/Whois/Object/RouteSet.pm
  28. 34  lib/Net/Whois/Object/RtrSet.pm
  29. 4  t/03-objects.t
  30. 68  t/105-AsBlock.t
  31. 74  t/110-AutNum.t
  32. 61  t/115-Person.t
  33. 68  t/120-Role.t
  34. 71  t/125-AsSet.t
  35. 80  t/130-Domain.t
  36. 78  t/135-InetNum.t
  37. 79  t/140-Inet6Num.t
  38. 71  t/145-InetRtr.t
  39. 63  t/150-RtrSet.t
  40. 74  t/155-Mntner.t
  41. 65  t/160-KeyCert.t
  42. 94  t/165-Route.t
  43. 92  t/167-Route6.t
  44. 64  t/170-RouteSet.t
  45. 60  t/175-PeeringSet.t
  46. 54  t/180-Limerick.t
  47. 60  t/185-Poem.t
  48. 44  t/187-PoeticForm.t
  49. 81  t/190-Organisation.t
  50. 20  t/195-Response.t
  51. 17  t/200-Information.t
  52. 88  t/205-Irt.t
  53. 61  t/210-FilterSet.t
  54. 67  t/215-SyncUpdates.t
1  Changes
... ...
@@ -1,6 +1,7 @@
1 1
 Revision history for net-whois-ripe
2 2
 
3 3
 
  4
+            - Add RIPE SyncUpdates prototype implementation (Create, Update, Delete)
4 5
             - Add type on attributes to prepare future update, with the 
5 6
               following methods :
6 7
                 attributes()
5  MANIFEST
@@ -8,8 +8,8 @@ lib/Net/Whois/Object/FilterSet.pm
8 8
 lib/Net/Whois/Object/Inet6Num.pm
9 9
 lib/Net/Whois/Object/InetNum.pm
10 10
 lib/Net/Whois/Object/InetRtr.pm
11  
-lib/Net/Whois/Object/Irt.pm
12 11
 lib/Net/Whois/Object/Information.pm
  12
+lib/Net/Whois/Object/Irt.pm
13 13
 lib/Net/Whois/Object/KeyCert.pm
14 14
 lib/Net/Whois/Object/Limerick.pm
15 15
 lib/Net/Whois/Object/Mntner.pm
@@ -57,6 +57,9 @@ t/190-Organisation.t
57 57
 t/195-Response.t
58 58
 t/200-Information.t
59 59
 t/205-Irt.t
  60
+t/210-FilterSet.t
  61
+t/215-SyncUpdates.t
60 62
 t/boilerplate.t
  63
+t/common.pl
61 64
 t/pod-coverage.t
62 65
 t/pod.t
3  credentials.sh
... ...
@@ -0,0 +1,3 @@
  1
+# source credentials.sh
  2
+export TEST_MNTNER=MA86905-MNT
  3
+export TEST_MNTNER_PASSWORD=totototo
264  lib/Net/Whois/Object.pm
@@ -4,6 +4,8 @@ use warnings;
4 4
 
5 5
 use Carp;
6 6
 use WWW::Mechanize;
  7
+use Net::Whois::RIPE;
  8
+use Data::Dumper;
7 9
 
8 10
 =head1 NAME
9 11
 
@@ -56,12 +58,61 @@ email.
56 58
 
57 59
 =head2 Update the RIPE database
58 60
 
59  
-This part is still to be done
  61
+The RIPE database update is currently under heavy development.
  62
+*The update code is to be considered as experimental.*
  63
+
  64
+We plan to offer several ways to update the RIPE database
60 65
 
61 66
 =head3 Update through the web interface.
62 67
 
63  
-Not implemented yet.
  68
+RIPE provides several web interfaces
  69
+
  70
+=head4 SyncUpdates (*Experimental*)
  71
+
  72
+Although not the latest one, this simple interface is the first to be wrapped
  73
+by this module.
  74
+
  75
+=head4 Create
  76
+
  77
+Once the object has been modified, locally, you can create it in the database
  78
+calling the syncupdates_create() method.
  79
+The only parameter being the associated maintener's password.
  80
+(Certificates are planned to be used in a near future)
  81
+
  82
+    $object->person('John Doe');
  83
+    ...
  84
+    my $primary_key = $object->syncupdates_create($password);
  85
+
  86
+The primary key of the object created is returned.
  87
+The attribute used as primary key can be obtained through 
  88
+$object->attribute('primary') 
  89
+
  90
+=head4 Update
  91
+
  92
+An object existing in the RIPE database, can be retrived, modified locally
  93
+and the updated through the syncupdates_update() method.
  94
+The only parameter being the associated maintener's password.
  95
+(Certificates are planned to be used in a near future)
  96
+
  97
+    $object->person('John Doe');
  98
+    ...
  99
+    $object->syncupdates_update($password);
  100
+
  101
+=head4 Update
64 102
 
  103
+An object existing in the RIPE database, can be retrived, and deleted in
  104
+the databased through the syncupdates_delete() method.
  105
+The only required parameter being the associated maintener's password.
  106
+(Certificates are planned to be used in a near future)
  107
+
  108
+    $object->syncupdates_update($password);
  109
+
  110
+An additional parameter can be used as a reason for the deletion.
  111
+
  112
+    $object->syncupdates_update($password,'Obsoleted by XXX');
  113
+
  114
+If no reason is provided, a default one ('Not needed anymore') is used.
  115
+    
65 116
 =head3 Update through email.
66 117
 
67 118
 Not implemented yet.
@@ -107,26 +158,27 @@ sub new {
107 158
         }
108 159
     }
109 160
 
110  
-    my ( $object, $block, @results );
  161
+    my ( $attribute, $block, $object, @results, $value );
111 162
 
112  
-    my ( $attribute, $value );
113 163
     for my $line (@lines) {
114 164
 
115  
-        if ( $line =~ /^(\S+):\s+(.*)/ ) {
  165
+        if ( $line =~ /^%(\S+)/ ) {
116 166
 
117  
-            # Attribute line
118  
-            $attribute = $1;
119  
-            $value     = $2;
  167
+            $block = 'response' unless $block;
  168
+
  169
+            # Response line
  170
+            $attribute = 'response';
  171
+            $value     = $1;
120 172
 
121 173
         }
122  
-        elsif ( $line =~ /^%(\S.*)/ ) {
  174
+        elsif ( $line =~ /^(\S+):\s+(.*)/ ) {
123 175
 
124  
-            # Response line
125  
-            $block = 'response';
126  
-            $value = $1;
  176
+            # Attribute line
  177
+            $attribute = $1;
  178
+            $value     = $2;
127 179
 
128 180
         }
129  
-        elsif ( $line =~ /^%\s(.*)/ ) {
  181
+        elsif ( $line =~ /^%\s+(.*)/ ) {
130 182
 
131 183
             $block = 'comment' unless $block;
132 184
 
@@ -188,14 +240,13 @@ Returns a list of attributes of the required type.
188 240
 =cut
189 241
 
190 242
 sub attributes {
191  
-    my ( $self, $type, $r_attributes ) = @_;
192  
-    if (not defined $type or $type =~ /all/i) {
193  
-        return ( $self->attributes('mandatory') , $self->attributes('optionnal'));
  243
+    my ( $self, $type, $ra_attributes ) = @_;
  244
+    if ( not defined $type or $type =~ /all/i ) {
  245
+        return ( $self->attributes('mandatory'), $self->attributes('optionnal') );
194 246
     }
195  
-    croak "Invalid attribute's type ($type)"    unless $type =~
196  
-    m/(all|primary|mandatory|optionnal|single|multiple)/i;
197  
-    if ($r_attributes) { 
198  
-        for my $a (@{$r_attributes}) {
  247
+    croak "Invalid attribute's type ($type)" unless $type =~ m/(all|primary|mandatory|optionnal|single|multiple)/i;
  248
+    if ($ra_attributes) {
  249
+        for my $a ( @{$ra_attributes} ) {
199 250
             $self->{TYPE}{$type}{$a} = 1;
200 251
         }
201 252
     }
@@ -211,7 +262,7 @@ This method return the RIPE class associated to the current object.
211 262
 sub class {
212 263
     my ( $self, $value ) = @_;
213 264
 
214  
-    return $self->_single_attribute_setget('class',$value); 
  265
+    return $self->_single_attribute_setget( 'class', $value );
215 266
 }
216 267
 
217 268
 =head2 B<attribute_is ( $attribute, $type )>
@@ -223,12 +274,12 @@ This method return true if $attribute is of type $type.
223 274
 sub attribute_is {
224 275
     my ( $self, $attribute, $type ) = @_;
225 276
 
226  
-    return defined $self->{TYPE}{$type}{$attribute}?1:0;
  277
+    return defined $self->{TYPE}{$type}{$attribute} ? 1 : 0;
227 278
 
228 279
     # for my $att ( $self->attributes( $type )) {
229 280
     #     if ($att eq $attribute) { return 1; }
230 281
     # }
231  
-    # return 0 ; 
  282
+    # return 0 ;
232 283
 }
233 284
 
234 285
 =head2 B<hidden_attributes( $attribute )>
@@ -267,23 +318,26 @@ Try to be as close as possible as the submited text.
267 318
 =cut
268 319
 
269 320
 sub dump {
270  
-    my ( $self ) = @_;
  321
+    my ($self) = @_;
271 322
 
272 323
     my %current_index;
273 324
     my $result;
274 325
 
275  
-    for my $line (@{ $self->{order} }) {
  326
+    for my $line ( @{ $self->{order} } ) {
276 327
         my $attribute = $line;
277 328
         $attribute =~ s/_/-/g;
278 329
 
279 330
         my $val = $self->$line();
280 331
 
281  
-        if (ref $val eq 'ARRAY') {
  332
+        if ( ref $val eq 'ARRAY' ) {
  333
+
282 334
             # If multi value get the lines in order
283  
-            $val = $val->[$current_index{$line}++];
  335
+            $val = $val->[ $current_index{$line}++ ];
284 336
         }
285 337
 
286  
-        $output = "$attribute:    $val\n";
  338
+        $val = '' unless $val;
  339
+
  340
+        my $output = "$attribute:    $val\n";
287 341
 
288 342
         # Process the comment
289 343
         $output =~ s/comment:\s+/\% /;
@@ -294,23 +348,81 @@ sub dump {
294 348
     return $result;
295 349
 }
296 350
 
297  
-=head2 B<web_update( $password )>
  351
+=head2 B<syncupdates_update( $password )>
298 352
 
299  
-Update the RIPE database through the web update interface.
  353
+Update the RIPE database through the web syncupdates interface.
300 354
 Use the password passed as parameter to authenticate.
301 355
 
302 356
 =cut
303 357
 
304  
-sub web_update {
  358
+sub syncupdates_update {
305 359
     my ( $self, $password ) = @_;
306 360
 
307  
-    my $mech = WWW::Mechanize->new();
308  
-    $mech->get(https://apps.db.ripe.net/webupdates/search.html);
  361
+    my ($key)  = $self->attributes('primary');
  362
+    my $value = $self->_single_attribute_setget($key);
309 363
 
  364
+    my $html = $self->_syncupdates_submit( $self->dump(), $password );
  365
+    
  366
+    if ( $html =~ /Modify SUCCEEDED:.*$value/m ) {
  367
+        return $value;
  368
+    }
  369
+    else {
  370
+        croak "Update not confirmed ($html)";
  371
+    }
  372
+}
310 373
 
  374
+=head2 B<syncupdates_delete( $password, [$reason] )>
311 375
 
312  
-    push @{ $self->{web_update} }, $web_update if defined $web_update;
313  
-    return @{ $self->{web_update} };
  376
+Delete the object in the RIPE database through the web syncupdates interface.
  377
+Use the password passed as parameter to authenticate.
  378
+The optionnal parmeter reason is used to explain why the object is deleted.
  379
+
  380
+=cut
  381
+
  382
+sub syncupdates_delete {
  383
+    my ( $self, $password, $reason ) = @_;
  384
+
  385
+    my ($key)  = $self->attributes('primary');
  386
+    my $value = $self->_single_attribute_setget($key);
  387
+
  388
+    my $text = $self->dump();
  389
+    $reason = 'Not needed anymore' unless $reason;
  390
+    $text .= "delete: $reason\n";
  391
+
  392
+    my $html = $self->_syncupdates_submit( $text, $password );
  393
+
  394
+    if ( $html =~ /Delete SUCCEEDED:.*$value/m ) {
  395
+        return $value;
  396
+    }
  397
+    else {
  398
+        croak "Deletion not confirmed ($html)";
  399
+    }
  400
+}
  401
+
  402
+=head2 B<syncupdates_create( $password )>
  403
+
  404
+Create an object in the the RIPE database through the web syncupdates interface.
  405
+Use the password passed as parameter to authenticate.
  406
+
  407
+Return the primary key of the object created.
  408
+
  409
+=cut
  410
+
  411
+sub syncupdates_create {
  412
+    my ( $self, $password ) = @_;
  413
+
  414
+    my ($key)  = $self->attributes('primary');
  415
+
  416
+    my $html = $self->_syncupdates_submit( $self->dump(), $password );
  417
+
  418
+    if ( $html =~ /\*\*\*Info:\s+Authorisation for\s+\[.+\]\s+(\S+)\s*$/m ) {
  419
+        my $value = $1;
  420
+        $self->_single_attribute_setget( $key, $value );
  421
+        return $value;
  422
+    }
  423
+    else {
  424
+        croak "No object KEY found ($html)";
  425
+    }
314 426
 }
315 427
 
316 428
 =begin UNDOCUMENTED
@@ -356,19 +468,20 @@ sub _object_factory {
356 468
                   rtr_set      => 'RtrSet',
357 469
     );
358 470
 
359  
-    die "Unrecognized Object ($type first attribute)" unless $class{$type};
  471
+    die "Unrecognized Object (first attribute: $type = $value)" unless $class{$type};
360 472
 
361 473
     my $class = "Net::Whois::Object::" . $class{$type};
362 474
 
363 475
     eval "require $class" or die "Can't require $class ($!)";
364 476
 
365 477
     # my $object = $class->new( $type => $value );
366  
-    my $object = $class->new(class => $class{$type} );
367  
-    
  478
+    my $object = $class->new( class => $class{$type} );
  479
+
368 480
     # First attribute is always single valued, except for comments
369 481
     if ( $type eq 'comment' ) {
370 482
         $object->_multiple_attribute_setget( $type => $value );
371  
-    } else {
  483
+    }
  484
+    else {
372 485
         $object->_single_attribute_setget( $type => $value );
373 486
     }
374 487
 
@@ -386,11 +499,12 @@ Generic setter/getter for singlevalue attribute.
386 499
 sub _single_attribute_setget {
387 500
     my ( $self, $attribute, $value ) = @_;
388 501
 
389  
-    if (defined $value) {
390  
-        # Store attribute order for dump, unless this attribute as already
391  
-        # been set
392  
-        push @{ $self->{order} }, $attribute    unless $self->{$attribute};
393  
-        
  502
+    if ( defined $value ) {
  503
+
  504
+        # Store attribute order for dump, unless this attribute as already been set
  505
+        #
  506
+        push @{ $self->{order} }, $attribute    unless $self->{$attribute} or $attribute eq 'class';
  507
+
394 508
         $self->{$attribute} = $value;
395 509
     }
396 510
     return $self->{$attribute};
@@ -407,16 +521,68 @@ Generic setter/getter for multivalue attribute.
407 521
 sub _multiple_attribute_setget {
408 522
     my ( $self, $attribute, $value ) = @_;
409 523
 
410  
-    if (defined $value) {
411  
-        # Store attribute order for dump, unless this attribute as already
412  
-        # been set
413  
-        push @{ $self->{order} }, $attribute;    # unless $update;
414  
-        
  524
+    if ( defined $value ) {
  525
+
  526
+        # Store attribute order for dump
  527
+        push @{ $self->{order} }, $attribute;    
  528
+
415 529
         push @{ $self->{$attribute} }, $value;
416 530
     }
  531
+
  532
+    croak "$attribute $self" unless ref $self;
417 533
     return $self->{$attribute};
418 534
 }
419 535
 
  536
+=head2 B<_syncupdates_submit( $text, $password )>
  537
+
  538
+Interact with the RIPE database through the web syncupdates interface.
  539
+Submit the text passed as parameter.
  540
+Use the password passed as parameter to authenticate.
  541
+The database used is chosen based on the 'source' attribute.
  542
+
  543
+Return the HTML code of the returned page.
  544
+(This will change in a near future)
  545
+
  546
+
  547
+=cut
  548
+
  549
+sub _syncupdates_submit {
  550
+    my ( $self, $text, $password ) = @_;
  551
+
  552
+    $text .= "password: $password\n" if $password;
  553
+
  554
+    my $mech = WWW::Mechanize->new();
  555
+
  556
+    $mech->get('https://apps.db.ripe.net/syncupdates/simple-rpsl.html');
  557
+
  558
+    my $form = $mech->form_number(2);
  559
+
  560
+    if ( $self->source() eq 'RIPE' ) {
  561
+
  562
+        # TODO bogus value during tests to prevent "leaks"
  563
+        $mech->set_fields( 'rpslBox:postRpsl:sourceRadioSelect' => 'AARIPE_NCC' );
  564
+    }
  565
+    else {
  566
+        $mech->set_fields( 'rpslBox:postRpsl:sourceRadioSelect' => 'TEST' );
  567
+    }
  568
+
  569
+    $mech->set_fields( 'rpslBox:postRpsl:sourceRadioSelect' => 'TEST' );
  570
+    $mech->set_fields( 'rpslBox:postRpsl:rpslObject'        => "$text\n" );
  571
+
  572
+    my $r = $mech->click_button( value => 'Update' );
  573
+
  574
+    croak "Can't submit to syncupdates : " . $mech->response()->status_linel unless $mech->success;
  575
+
  576
+    my $page = $mech->response()->content;
  577
+
  578
+    if ( $page !~ /Number of objects processed successfully:  1/s ) {
  579
+
  580
+        # carp "Syncupdate failed :\n$page\n";
  581
+    }
  582
+
  583
+    return $page;
  584
+}
  585
+
420 586
 =head1 TODO
421 587
 
422 588
 The update part (RIPE database) is still missing, but I'm planning to offer a way
32  lib/Net/Whois/Object/AsBlock.pm
@@ -48,11 +48,11 @@ sub new {
48 48
         $self->$key( $options{$key} );
49 49
     }
50 50
 
51  
-    $self->attributes('primary',['as_block']);
52  
-    $self->attributes('mandatory',['as_block', 'admin_c', 'tech_c', 'mnt_by', 'changed', 'source']);
53  
-    $self->attributes('optionnal',['descr', 'remarks', 'org', 'notify', 'mnt_lower']);
54  
-    $self->attributes('single',['as_block', 'source']);
55  
-    $self->attributes('multiple',['descr', 'remarks', 'org', 'admin_c', 'tech_c', 'notify', 'mnt_lower', 'mnt_by', 'changed']);
  51
+    $self->attributes( 'primary', ['as_block'] );
  52
+    $self->attributes( 'mandatory', [ 'as_block', 'admin_c', 'tech_c', 'mnt_by', 'changed', 'source' ] );
  53
+    $self->attributes( 'optionnal', [ 'descr', 'remarks', 'org', 'notify', 'mnt_lower' ] );
  54
+    $self->attributes( 'single', [ 'as_block', 'source' ] );
  55
+    $self->attributes( 'multiple', [ 'descr', 'remarks', 'org', 'admin_c', 'tech_c', 'notify', 'mnt_lower', 'mnt_by', 'changed' ] );
56 56
 
57 57
     return $self;
58 58
 }
@@ -75,7 +75,7 @@ stored in the appropriate Internet Registry's Whois Database.
75 75
 sub as_block {
76 76
     my ( $self, $as_block ) = @_;
77 77
 
78  
-    return $self->_single_attribute_setget('as_block',$as_block);
  78
+    return $self->_single_attribute_setget( 'as_block', $as_block );
79 79
 }
80 80
 
81 81
 =head2 B<descr( [$descr] )>
@@ -91,7 +91,7 @@ in the as-block.
91 91
 sub descr {
92 92
     my ( $self, $descr ) = @_;
93 93
 
94  
-    return $self->_multiple_attribute_setget('descr',$descr);
  94
+    return $self->_multiple_attribute_setget( 'descr', $descr );
95 95
 }
96 96
 
97 97
 =head2 B<remarks( [$remarks] )>
@@ -111,7 +111,7 @@ the AS numbers.
111 111
 sub remarks {
112 112
     my ( $self, $remarks ) = @_;
113 113
 
114  
-    return $self->_multiple_attribute_setget('remarks',$remarks);
  114
+    return $self->_multiple_attribute_setget( 'remarks', $remarks );
115 115
 }
116 116
 
117 117
 =head2 B<tech_c( [$tech_c] )>
@@ -134,7 +134,7 @@ physically located at the site of the network.
134 134
 sub tech_c {
135 135
     my ( $self, $tech_c ) = @_;
136 136
 
137  
-    return $self->_multiple_attribute_setget('tech_c',$tech_c);
  137
+    return $self->_multiple_attribute_setget( 'tech_c', $tech_c );
138 138
 }
139 139
 
140 140
 =head2 B<admin_c( [$admin_c])>
@@ -154,7 +154,7 @@ located at the site of the network.
154 154
 sub admin_c {
155 155
     my ( $self, $admin_c ) = @_;
156 156
 
157  
-    return $self->_multiple_attribute_setget('admin_c',$admin_c);
  157
+    return $self->_multiple_attribute_setget( 'admin_c', $admin_c );
158 158
 }
159 159
 
160 160
 =head2 B<notify( [$notify] )>
@@ -171,7 +171,7 @@ to the object should be sent.
171 171
 sub notify {
172 172
     my ( $self, $notify ) = @_;
173 173
 
174  
-    return $self->_multiple_attribute_setget('notify',$notify);
  174
+    return $self->_multiple_attribute_setget( 'notify', $notify );
175 175
 }
176 176
 
177 177
 =head2 B<mnt_lower( [$mnt_lower] )>
@@ -191,7 +191,7 @@ authorization.
191 191
 sub mnt_lower {
192 192
     my ( $self, $mnt_lower ) = @_;
193 193
 
194  
-    return $self->_multiple_attribute_setget('mnt_lower',$mnt_lower);
  194
+    return $self->_multiple_attribute_setget( 'mnt_lower', $mnt_lower );
195 195
 }
196 196
 
197 197
 =head2 B<mnt_by( [$mnt_by] )>
@@ -212,7 +212,7 @@ object will be able to change details.
212 212
 sub mnt_by {
213 213
     my ( $self, $mnt_by ) = @_;
214 214
 
215  
-    return $self->_multiple_attribute_setget('mnt_by',$mnt_by);
  215
+    return $self->_multiple_attribute_setget( 'mnt_by', $mnt_by );
216 216
 }
217 217
 
218 218
 =head2 B<changed( [$changed] )>
@@ -235,7 +235,7 @@ format using one of the following two formats: YYYYMMDD or YYMMDD.
235 235
 sub changed {
236 236
     my ( $self, $changed ) = @_;
237 237
 
238  
-    return $self->_multiple_attribute_setget('changed',$changed);
  238
+    return $self->_multiple_attribute_setget( 'changed', $changed );
239 239
 }
240 240
 
241 241
 =head2 B<source( [$source] )>
@@ -250,7 +250,7 @@ The database where the object is registered.
250 250
 sub source {
251 251
     my ( $self, $source ) = @_;
252 252
 
253  
-    return $self->_single_attribute_setget('source',$source);
  253
+    return $self->_single_attribute_setget( 'source', $source );
254 254
 }
255 255
 
256 256
 =head2 B<org( [$org] )>
@@ -265,7 +265,7 @@ The organisation entity this object is bound to.
265 265
 sub org {
266 266
     my ( $self, $org ) = @_;
267 267
 
268  
-    return $self->_single_attribute_setget('org',$org);
  268
+    return $self->_single_attribute_setget( 'org', $org );
269 269
 }
270 270
 
271 271
 1;
32  lib/Net/Whois/Object/AsSet.pm
@@ -43,11 +43,11 @@ sub new {
43 43
         $self->$key( $options{$key} );
44 44
     }
45 45
 
46  
-    $self->attributes('primary',['as_set']);
47  
-    $self->attributes('mandatory',['as_set', 'descr', 'tech_c', 'admin_c', 'mnt_by', 'changed', 'source']);
48  
-    $self->attributes('optionnal',['members', 'mbrs_by_ref', 'remarks', 'notify']);
49  
-    $self->attributes('single',['as_set', 'source']);
50  
-    $self->attributes('multiple',['descr', 'members', 'mbrs_by_ref', 'remarks', 'tech_c', 'admin_c', 'notify', 'mnt_by', 'changed']);
  46
+    $self->attributes( 'primary', ['as_set'] );
  47
+    $self->attributes( 'mandatory', [ 'as_set', 'descr', 'tech_c', 'admin_c', 'mnt_by', 'changed', 'source' ] );
  48
+    $self->attributes( 'optionnal', [ 'members', 'mbrs_by_ref', 'remarks', 'notify' ] );
  49
+    $self->attributes( 'single', [ 'as_set', 'source' ] );
  50
+    $self->attributes( 'multiple', [ 'descr', 'members', 'mbrs_by_ref', 'remarks', 'tech_c', 'admin_c', 'notify', 'mnt_by', 'changed' ] );
51 51
 
52 52
     return $self;
53 53
 }
@@ -68,7 +68,7 @@ with 'as-'.
68 68
 sub as_set {
69 69
     my ( $self, $as_set ) = @_;
70 70
 
71  
-    return $self->_single_attribute_setget('as_set',$as_set);
  71
+    return $self->_single_attribute_setget( 'as_set', $as_set );
72 72
 }
73 73
 
74 74
 =head2 B<descr( [$descr] )>
@@ -84,7 +84,7 @@ A short description related to the object's purpose.
84 84
 sub descr {
85 85
     my ( $self, $descr ) = @_;
86 86
 
87  
-    return $self->_multiple_attribute_setget('descr',$descr);
  87
+    return $self->_multiple_attribute_setget( 'descr', $descr );
88 88
 }
89 89
 
90 90
 =head2 B<members( [$member] )>
@@ -101,7 +101,7 @@ of AS Numbers, or other as-set names.
101 101
 sub members {
102 102
     my ( $self, $member ) = @_;
103 103
 
104  
-    return $self->_multiple_attribute_setget('member',$member);
  104
+    return $self->_multiple_attribute_setget( 'member', $member );
105 105
 }
106 106
 
107 107
 =head2 B<mbrs_by_ref( [$mbr] )>
@@ -127,7 +127,7 @@ defined explicitly by the members attribute.
127 127
 sub mbrs_by_ref {
128 128
     my ( $self, $mbr ) = @_;
129 129
 
130  
-    return $self->_multiple_attribute_setget('mbr',$mbr);
  130
+    return $self->_multiple_attribute_setget( 'mbr', $mbr );
131 131
 }
132 132
 
133 133
 =head2 B<remarks( [$remark] )>
@@ -144,7 +144,7 @@ May include a URL or email address.
144 144
 sub remarks {
145 145
     my ( $self, $remark ) = @_;
146 146
 
147  
-    return $self->_multiple_attribute_setget('remarks',$remark);
  147
+    return $self->_multiple_attribute_setget( 'remarks', $remark );
148 148
 }
149 149
 
150 150
 =head2 B<tech_c( [$tech_c] )>
@@ -166,7 +166,7 @@ physically located at the site of the network.
166 166
 sub tech_c {
167 167
     my ( $self, $tech_c ) = @_;
168 168
 
169  
-    return $self->_multiple_attribute_setget('tech_c',$tech_c);
  169
+    return $self->_multiple_attribute_setget( 'tech_c', $tech_c );
170 170
 }
171 171
 
172 172
 =head2 B<admin_c( [$admin_c] )>
@@ -186,7 +186,7 @@ located at the site of the network.
186 186
 sub admin_c {
187 187
     my ( $self, $admin_c ) = @_;
188 188
 
189  
-    return $self->_multiple_attribute_setget('admin_c',$admin_c);
  189
+    return $self->_multiple_attribute_setget( 'admin_c', $admin_c );
190 190
 }
191 191
 
192 192
 =head2 B<notify( [$notify] )>
@@ -203,7 +203,7 @@ sent.
203 203
 sub notify {
204 204
     my ( $self, $notify ) = @_;
205 205
 
206  
-    return $self->_multiple_attribute_setget('notify',$notify);
  206
+    return $self->_multiple_attribute_setget( 'notify', $notify );
207 207
 }
208 208
 
209 209
 =head2 B<mnt_by( [$mnt] )>
@@ -224,7 +224,7 @@ object will be able to change details.
224 224
 sub mnt_by {
225 225
     my ( $self, $mnt ) = @_;
226 226
 
227  
-    return $self->_multiple_attribute_setget('mnt',$mnt);
  227
+    return $self->_multiple_attribute_setget( 'mnt', $mnt );
228 228
 }
229 229
 
230 230
 =head2 B<changed( [$changed] )>
@@ -247,7 +247,7 @@ format using one of the following two formats: YYYYMMDD or YYMMDD.
247 247
 sub changed {
248 248
     my ( $self, $changed ) = @_;
249 249
 
250  
-    return $self->_multiple_attribute_setget('changed',$changed);
  250
+    return $self->_multiple_attribute_setget( 'changed', $changed );
251 251
 }
252 252
 
253 253
 =head2 B<source( [$source] )>
@@ -262,7 +262,7 @@ The database where the object is registered.
262 262
 sub source {
263 263
     my ( $self, $source ) = @_;
264 264
 
265  
-    return $self->_single_attribute_setget('source',$source);
  265
+    return $self->_single_attribute_setget( 'source', $source );
266 266
 }
267 267
 
268 268
 1;
50  lib/Net/Whois/Object/AutNum.pm
@@ -25,7 +25,6 @@ use base qw/Net::Whois::Object/;
25 25
 # changed:       [mandatory]  [multiple]   [ ]
26 26
 # source:        [mandatory]  [single]     [ ]
27 27
 
28  
-
29 28
 =head1 NAME
30 29
 
31 30
 Net::Whois::Object::AutNum - an object representation of a RPSL AutNum block
@@ -56,12 +55,11 @@ sub new {
56 55
         $self->$key( $options{$key} );
57 56
     }
58 57
 
59  
-    $self->attributes('primary',['aut_num']);
60  
-    $self->attributes('mandatory',['aut_num', 'as_name', 'descr', 'tech_c', 'admin_c', 'mnt_by', 'changed', 'source']);
  58
+    $self->attributes( 'primary',   ['aut_num'] );
  59
+    $self->attributes( 'mandatory', [ 'aut_num', 'as_name', 'descr', 'tech_c', 'admin_c', 'mnt_by', 'changed', 'source' ] );
61 60
     $self->attributes( 'optionnal', [ 'member_of', 'import', 'mp_import', 'export', 'mp_export', 'default', 'mp_default', 'remarks', 'notify', 'mnt_lower', 'mnt_routes' ] );
62  
-    $self->attributes('single',['aut_num', 'as_name', 'source']);
63  
-    $self->attributes('multiple',['descr', 'member_of', 'import', 'mp_import', 'export', 'mp_export', 'default', 'mp_default', 'remarks',
64  
-            'admin_c', 'tech_c', 'notify', 'mnt_lower', 'mnt_routes', 'mnt_by', 'changed']);
  61
+    $self->attributes( 'single', [ 'aut_num', 'as_name', 'source' ] );
  62
+    $self->attributes( 'multiple', [ 'descr', 'member_of', 'import', 'mp_import', 'export', 'mp_export', 'default', 'mp_default', 'remarks', 'admin_c', 'tech_c', 'notify', 'mnt_lower', 'mnt_routes', 'mnt_by', 'changed' ] );
65 63
 
66 64
     return $self;
67 65
 }
@@ -87,7 +85,7 @@ sub aut_num {
87 85
         warn "Illegal aut-num ($aut_num) : should be ASn, n being a 32 bit number with no leading 0";
88 86
     }
89 87
 
90  
-    return $self->_single_attribute_setget('aut_num',$aut_num);
  88
+    return $self->_single_attribute_setget( 'aut_num', $aut_num );
91 89
 }
92 90
 
93 91
 =head2 B<as_name( [$as_name] )>
@@ -102,7 +100,7 @@ The as-name attribute is a symbolic name of the AS.
102 100
 sub as_name {
103 101
     my ( $self, $as_name ) = @_;
104 102
 
105  
-    return $self->_single_attribute_setget('as_name',$as_name);
  103
+    return $self->_single_attribute_setget( 'as_name', $as_name );
106 104
 }
107 105
 
108 106
 =head2 B<descr( [$descr] )>
@@ -115,7 +113,7 @@ Accepts an optional descr value to be added to the descr array, always return th
115 113
 sub descr {
116 114
     my ( $self, $descr ) = @_;
117 115
 
118  
-    return $self->_multiple_attribute_setget('descr',$descr);
  116
+    return $self->_multiple_attribute_setget( 'descr', $descr );
119 117
 }
120 118
 
121 119
 =head2 B<member_of( [$mbr_of] )>
@@ -141,7 +139,7 @@ and/or list the AS number in the members attribute
141 139
 sub member_of {
142 140
     my ( $self, $member_of ) = @_;
143 141
 
144  
-    return $self->_multiple_attribute_setget('member_of',$member_of);
  142
+    return $self->_multiple_attribute_setget( 'member_of', $member_of );
145 143
 }
146 144
 
147 145
 =head2 B<import( [$import] )>
@@ -157,7 +155,7 @@ The inbound IPv4 routing policy of the AS.
157 155
 sub import {
158 156
     my ( $self, $import ) = @_;
159 157
 
160  
-    return $self->_multiple_attribute_setget('import',$import);
  158
+    return $self->_multiple_attribute_setget( 'import', $import );
161 159
 }
162 160
 
163 161
 =head2 B<mp_import( [$import] )>
@@ -173,7 +171,7 @@ The inbound IPv6 routing policy of the AS.
173 171
 sub mp_import {
174 172
     my ( $self, $mp_import ) = @_;
175 173
 
176  
-    return $self->_multiple_attribute_setget('mp_import',$mp_import);
  174
+    return $self->_multiple_attribute_setget( 'mp_import', $mp_import );
177 175
 }
178 176
 
179 177
 =head2 B<export( [$export] )>
@@ -189,7 +187,7 @@ The outbound routing policy of the AS.
189 187
 sub export {
190 188
     my ( $self, $export ) = @_;
191 189
 
192  
-    return $self->_multiple_attribute_setget('export',$export);
  190
+    return $self->_multiple_attribute_setget( 'export', $export );
193 191
 }
194 192
 
195 193
 =head2 B<mp_export( [$mp_export] )>
@@ -205,7 +203,7 @@ The outbound IPv6 routing policy of the AS.
205 203
 sub mp_export {
206 204
     my ( $self, $mp_export ) = @_;
207 205
 
208  
-    return $self->_multiple_attribute_setget('mp_export',$mp_export);
  206
+    return $self->_multiple_attribute_setget( 'mp_export', $mp_export );
209 207
 }
210 208
 
211 209
 =head2 B<default( [$default] )>
@@ -222,7 +220,7 @@ more-specific information on where to send the traffic.
222 220
 sub default {
223 221
     my ( $self, $default ) = @_;
224 222
 
225  
-    return $self->_multiple_attribute_setget('default',$default);
  223
+    return $self->_multiple_attribute_setget( 'default', $default );
226 224
 }
227 225
 
228 226
 =head2 B<mp_default( [$mp_default] )>
@@ -240,7 +238,7 @@ specified.
240 238
 sub mp_default {
241 239
     my ( $self, $mp_default ) = @_;
242 240
 
243  
-    return $self->_multiple_attribute_setget('mp_default',$mp_default);
  241
+    return $self->_multiple_attribute_setget( 'mp_default', $mp_default );
244 242
 }
245 243
 
246 244
 =head2 B<remarks( [$remark] )>
@@ -257,7 +255,7 @@ include a URL or email address.
257 255
 sub remarks {
258 256
     my ( $self, $remark ) = @_;
259 257
 
260  
-    return $self->_multiple_attribute_setget('remark',$remark);
  258
+    return $self->_multiple_attribute_setget( 'remark', $remark );
261 259
 }
262 260
 
263 261
 =head2 B<admin_c( [$contact] )>
@@ -277,7 +275,7 @@ located at the site of the network.
277 275
 sub admin_c {
278 276
     my ( $self, $contact ) = @_;
279 277
 
280  
-    return $self->_multiple_attribute_setget('admin_c',$contact);
  278
+    return $self->_multiple_attribute_setget( 'admin_c', $contact );
281 279
 }
282 280
 
283 281
 =head2 B<tech_c( [$contact] )>
@@ -299,7 +297,7 @@ physically located at the site of the network.
299 297
 sub tech_c {
300 298
     my ( $self, $contact ) = @_;
301 299
 
302  
-    return $self->_multiple_attribute_setget('tech_c',$contact);
  300
+    return $self->_multiple_attribute_setget( 'tech_c', $contact );
303 301
 }
304 302
 
305 303
 =head2 B<notify( [$notify] )>
@@ -313,7 +311,7 @@ always return the current notify array.
313 311
 sub notify {
314 312
     my ( $self, $notify ) = @_;
315 313
 
316  
-    return $self->_multiple_attribute_setget('notify',$notify);
  314
+    return $self->_multiple_attribute_setget( 'notify', $notify );
317 315
 }
318 316
 
319 317
 =head2 B<mnt_lower( [$mnt_lower] )>
@@ -327,7 +325,7 @@ always return the current mnt_lower array.
327 325
 sub mnt_lower {
328 326
     my ( $self, $mnt_lower ) = @_;
329 327
 
330  
-    return $self->_multiple_attribute_setget('mnt_lower',$mnt_lower);
  328
+    return $self->_multiple_attribute_setget( 'mnt_lower', $mnt_lower );
331 329
 }
332 330
 
333 331
 =head2 B<mnt_routes( [$mnt_routes] )>
@@ -341,7 +339,7 @@ always return the current mnt_routes array.
341 339
 sub mnt_routes {
342 340
     my ( $self, $mnt_routes ) = @_;
343 341
 
344  
-    return $self->_multiple_attribute_setget('mnt_route',$mnt_route);
  342
+    return $self->_multiple_attribute_setget( 'mnt_route', $mnt_route );
345 343
 }
346 344
 
347 345
 =head2 B<mnt_by( [$mnt_by] )>
@@ -355,7 +353,7 @@ always return the current mnt_by array.
355 353
 sub mnt_by {
356 354
     my ( $self, $mnt_by ) = @_;
357 355
 
358  
-    return $self->_multiple_attribute_setget('mnt_by',$mnt_by);
  356
+    return $self->_multiple_attribute_setget( 'mnt_by', $mnt_by );
359 357
 }
360 358
 
361 359
 =head2 B<changed( [$changed] )>
@@ -369,7 +367,7 @@ always return the current changed array.
369 367
 sub changed {
370 368
     my ( $self, $changed ) = @_;
371 369
 
372  
-    return $self->_multiple_attribute_setget('changed',$changed);
  370
+    return $self->_multiple_attribute_setget( 'changed', $changed );
373 371
 }
374 372
 
375 373
 =head2 B<source( [$source] )>
@@ -384,7 +382,7 @@ The database where the object is registered.
384 382
 sub source {
385 383
     my ( $self, $source ) = @_;
386 384
 
387  
-    return $self->_single_attribute_setget('source',$source);
  385
+    return $self->_single_attribute_setget( 'source', $source );
388 386
 }
389 387
 
390 388
 =head2 B<org( [$org] )>
@@ -400,7 +398,7 @@ This is to ensure only one organisation is responsible for this resource.
400 398
 sub org {
401 399
     my ( $self, $org ) = @_;
402 400
 
403  
-    return $self->_single_attribute_setget('org',$org);
  401
+    return $self->_single_attribute_setget( 'org', $org );
404 402
 }
405 403
 
406 404
 1;
43  lib/Net/Whois/Object/Domain.pm
@@ -50,12 +50,11 @@ sub new {
50 50
         $self->$key( $options{$key} );
51 51
     }
52 52
 
53  
-    $self->attributes('primary',['domain']);
54  
-    $self->attributes('mandatory',['domain',  'descr', 'tech_c', 'admin_c', 'zone_c', 'changed', 'source']);
  53
+    $self->attributes( 'primary',   ['domain'] );
  54
+    $self->attributes( 'mandatory', [ 'domain', 'descr', 'tech_c', 'admin_c', 'zone_c', 'changed', 'source' ] );
55 55
     $self->attributes( 'optionnal', [ 'org', 'nserver', 'ds_rdata', 'sub_dom', 'dom_net', 'remarks', 'notify', 'mnt_by', 'mnt_lower', 'refer' ] );
56  
-    $self->attributes('single',['domain', 'refer', 'source']);
57  
-    $self->attributes('multiple',['descr', 'org', 'admin_c', 'tech_c', 'zone_c', 'nserver', 'ds_rdata', 'sub_dom', 'dom_net', 'remarks',
58  
-            'notify', 'mnt_by', 'mnt_lower', 'changed']);
  56
+    $self->attributes( 'single', [ 'domain', 'refer', 'source' ] );
  57
+    $self->attributes( 'multiple', [ 'descr', 'org', 'admin_c', 'tech_c', 'zone_c', 'nserver', 'ds_rdata', 'sub_dom', 'dom_net', 'remarks', 'notify', 'mnt_by', 'mnt_lower', 'changed' ] );
59 58
 
60 59
     return $self;
61 60
 }
@@ -76,7 +75,7 @@ sub domain {
76 75
     # Enforce the format
77 76
     $domain =~ s/\.$// if $domain;
78 77
 
79  
-    return $self->_single_attribute_setget('domain',$domain);
  78
+    return $self->_single_attribute_setget( 'domain', $domain );
80 79
 }
81 80
 
82 81
 =head2 B<descr( [$descr] )>
@@ -93,7 +92,7 @@ describe the use of the IP range described in the domain object.
93 92
 sub descr {
94 93
     my ( $self, $descr ) = @_;
95 94
 
96  
-    return $self->_multiple_attribute_setget('descr',$descr);
  95
+    return $self->_multiple_attribute_setget( 'descr', $descr );
97 96
 }
98 97
 
99 98
 =head2 B<org( [$org] )>
@@ -109,7 +108,7 @@ The organisation responsible for this domain.
109 108
 sub org {
110 109
     my ( $self, $org ) = @_;
111 110
 
112  
-    return $self->_multiple_attribute_setget('org',$org);
  111
+    return $self->_multiple_attribute_setget( 'org', $org );
113 112
 }
114 113
 
115 114
 =head2 B<admin_c( [$contact] )>
@@ -129,7 +128,7 @@ located at the site of the network.
129 128
 sub admin_c {
130 129
     my ( $self, $contact ) = @_;
131 130
 
132  
-    return $self->_multiple_attribute_setget('admin_c',$contact);
  131
+    return $self->_multiple_attribute_setget( 'admin_c', $contact );
133 132
 }
134 133
 
135 134
 =head2 B<tech_c( [$contact] )>
@@ -151,7 +150,7 @@ physically located at the site of the network.
151 150
 sub tech_c {
152 151
     my ( $self, $contact ) = @_;
153 152
 
154  
-    return $self->_multiple_attribute_setget('tech_c',$contact);
  153
+    return $self->_multiple_attribute_setget( 'tech_c', $contact );
155 154
 }
156 155
 
157 156
 =head2 B<zone_c( [$contact] )>
@@ -167,7 +166,7 @@ The NIC-handle of a 'person' or 'role' object with authority over a zone.
167 166
 sub zone_c {
168 167
     my ( $self, $contact ) = @_;
169 168
 
170  
-    return $self->_multiple_attribute_setget('zone_c',$contact);
  169
+    return $self->_multiple_attribute_setget( 'zone_c', $contact );
171 170
 }
172 171
 
173 172
 =head2 B<nserver( [$server] )>
@@ -184,7 +183,7 @@ mandatory.
184 183
 sub nserver {
185 184
     my ( $self, $server ) = @_;
186 185
 
187  
-    return $self->_multiple_attribute_setget('nserver',$server);
  186
+    return $self->_multiple_attribute_setget( 'nserver', $server );
188 187
 }
189 188
 
190 189
 =head2 B<ds_rdata( [$server] )>
@@ -201,7 +200,7 @@ for DNSSEC (short for DNS Security Extensions)
201 200
 sub ds_rdata {
202 201
     my ( $self, $server ) = @_;
203 202
 
204  
-    return $self->_multiple_attribute_setget('ds_data',$server);
  203
+    return $self->_multiple_attribute_setget( 'ds_data', $server );
205 204
 }
206 205
 
207 206
 =head2 B<sub_dom( [$dom] )>
@@ -219,7 +218,7 @@ contains this attribute
219 218
 sub sub_dom {
220 219
     my ( $self, $dom ) = @_;
221 220
 
222  
-    return $self->_multiple_attribute_setget('sub_dom',$dom);
  221
+    return $self->_multiple_attribute_setget( 'sub_dom', $dom );
223 222
 }
224 223
 
225 224
 =head2 B<dom_net( [$dom_net] )>
@@ -235,7 +234,7 @@ The dom_net attribute contains a list of IP networks in a domain.
235 234
 sub dom_net {
236 235
     my ( $self, $dom_net ) = @_;
237 236
 
238  
-    return $self->_multiple_attribute_setget('dom_net',$dom_net);
  237
+    return $self->_multiple_attribute_setget( 'dom_net', $dom_net );
239 238
 }
240 239
 
241 240
 =head2 B<remarks( [$remark] )>
@@ -251,7 +250,7 @@ General remarks. May include a URL or email address.
251 250
 sub remarks {
252 251
     my ( $self, $remark ) = @_;
253 252
 
254  
-    return $self->_multiple_attribute_setget('remarks',$remark);
  253
+    return $self->_multiple_attribute_setget( 'remarks', $remark );
255 254
 }
256 255
 
257 256
 =head2 B<notify( [$notify] )>
@@ -268,7 +267,7 @@ sent.
268 267
 sub notify {
269 268
     my ( $self, $notify ) = @_;
270 269
 
271  
-    return $self->_multiple_attribute_setget('notify',$notify);
  270
+    return $self->_multiple_attribute_setget( 'notify', $notify );
272 271
 }
273 272
 
274 273
 =head2 B<mnt_by( [$mnt_by] )>
@@ -285,7 +284,7 @@ this object.
285 284
 sub mnt_by {
286 285
     my ( $self, $mnt_by ) = @_;
287 286
 
288  
-    return $self->_multiple_attribute_setget('mnt_by',$mnt_by);
  287
+    return $self->_multiple_attribute_setget( 'mnt_by', $mnt_by );
289 288
 }
290 289
 
291 290
 =head2 B<mnt_lower( [$mnt_lower] )>
@@ -303,7 +302,7 @@ object.
303 302
 sub mnt_lower {
304 303
     my ( $self, $mnt_lower ) = @_;
305 304
 
306  
-    return $self->_multiple_attribute_setget('mnt_lower',$mnt_lower);
  305
+    return $self->_multiple_attribute_setget( 'mnt_lower', $mnt_lower );
307 306
 }
308 307
 
309 308
 =head2 B<refer( [$refer] )>
@@ -321,7 +320,7 @@ removed and may be deprecated.
321 320
 sub refer {
322 321
     my ( $self, $refer ) = @_;
323 322
 
324  
-    return $self->_single_attribute_setget('refer',$refer);
  323
+    return $self->_single_attribute_setget( 'refer', $refer );
325 324
 }
326 325
 
327 326
 =head2 B<changed( [$changed] )>
@@ -344,7 +343,7 @@ format using one of the following two formats: YYYYMMDD or YYMMDD.
344 343
 sub changed {
345 344
     my ( $self, $changed ) = @_;
346 345
 
347  
-    return $self->_multiple_attribute_setget('changed',$changed);
  346
+    return $self->_multiple_attribute_setget( 'changed', $changed );
348 347
 }
349 348
 
350 349
 =head2 B<source( [$source] )>
@@ -359,7 +358,7 @@ The database where the object is registered.
359 358
 sub source {
360 359
     my ( $self, $source ) = @_;
361 360
 
362  
-    return $self->_single_attribute_setget('source',$source);
  361
+    return $self->_single_attribute_setget( 'source', $source );
363 362
 }
364 363
 
365 364
 1;
38  lib/Net/Whois/Object/FilterSet.pm
@@ -46,11 +46,11 @@ sub new {
46 46
         $self->$key( $options{$key} );
47 47
     }
48 48
 
49  
-    $self->attributes('primary',['filter_set']);
50  
-    $self->attributes('mandatory',['filter_set', 'filter', 'mp_filter', 'source']);
51  
-    $self->attributes( 'optionnal', [ 'remarks', 'org', 'notify', 'mnt_lower'] );
52  
-    $self->attributes('single',['filter_set', 'filter', 'mp_filter', 'source']);
53  
-    $self->attributes('multiple',['descr', 'remarks', 'org', 'tech_c', 'admin_c', 'notify', 'mnt_by', 'mnt_lower', 'changed']);
  49
+    $self->attributes( 'primary',   ['filter_set'] );
  50
+    $self->attributes( 'mandatory', [ 'filter_set', 'filter', 'mp_filter', 'source' ] );
  51
+    $self->attributes( 'optionnal', [ 'remarks', 'org', 'notify', 'mnt_lower' ] );
  52
+    $self->attributes( 'single',    [ 'filter_set', 'filter', 'mp_filter', 'source' ] );
  53
+    $self->attributes( 'multiple',  [ 'descr', 'remarks', 'org', 'tech_c', 'admin_c', 'notify', 'mnt_by', 'mnt_lower', 'changed' ] );
54 54
 
55 55
     return $self;
56 56
 }
@@ -74,11 +74,11 @@ components of a hierarchical filter-name have to be filter_set names.
74 74
 
75 75
 sub filter_set {
76 76
     my ( $self, $filter_set ) = @_;
77  
-    if ($filter_set and $filter_set !~/^fltr-/i) {
  77
+    if ( $filter_set and $filter_set !~ /^fltr-/i ) {
78 78
         warn "Incorrect FilterSet's name ($filter_set) : Should start with 'FLTR-'";
79 79
     }
80 80
 
81  
-    return $self->_single_attribute_setget('filter_set',$filter_set);
  81
+    return $self->_single_attribute_setget( 'filter_set', $filter_set );
82 82
 }
83 83
 
84 84
 =head2 B<descr( [$descr] )>
@@ -94,7 +94,7 @@ A short description related to the object's purpose.
94 94
 sub descr {
95 95
     my ( $self, $descr ) = @_;
96 96
 
97  
-    return $self->_multiple_attribute_setget('descr',$descr);
  97
+    return $self->_multiple_attribute_setget( 'descr', $descr );
98 98
 }
99 99
 
100 100
 =head2 B<filter( [$filter] )>
@@ -113,7 +113,7 @@ you have said you want to see.
113 113
 sub filter {
114 114
     my ( $self, $filter ) = @_;
115 115
 
116  
-    return $self->_single_attribute_setget('filter',$filter);
  116
+    return $self->_single_attribute_setget( 'filter', $filter );
117 117
 }
118 118
 
119 119
 =head2 B<mp_filter( [$mp_filter] )>
@@ -129,7 +129,7 @@ a subset of these routes.
129 129
 sub mp_filter {
130 130
     my ( $self, $mp_filter ) = @_;
131 131
 
132  
-    return $self->_single_attribute_setget('mp_filter',$mp_filter);
  132
+    return $self->_single_attribute_setget( 'mp_filter', $mp_filter );
133 133
 }
134 134
 
135 135
 =head2 B<remarks( [$remark] )>
@@ -145,7 +145,7 @@ General remarks. May include a URL or email address.
145 145
 sub remarks {
146 146
     my ( $self, $remark ) = @_;
147 147
 
148  
-    return $self->_multiple_attribute_setget('remarks',$remark);
  148
+    return $self->_multiple_attribute_setget( 'remarks', $remark );
149 149
 }