Thinking Moose

For my Moose-pen today I am going to have to put my thinking moose and get out of my class, type, attribute and coercion rut that I have been and and look at how my Accessor will be used by other programmers.

Fortunetly I have not done a good deal of work in this area. So far I have only the retrieve and my 'BUILD' sub that I use to load in the DAD that might be out test. Now this is where I am getting into problems as the way it stands not thing will work fine with static Accessor but I will have problems with adding in dynamic attributes.

To illustrate this lets start with a simple example of two joined tables.
          +------------+        +-----------+
          | Users      |        | Countries |
          +------------|        +-----------+
          | f_name     |        | id        |
          | l_name     |        | name      |
          | country_id |        +-----------+
          +------------+
now my Accessor call will look like this

Mocking Should Not Require Interfaces

Exploring the ecosystem outside Perl, I have found multiple examples of languages and frameworks that require you to implement your classes as an interface + an underlying engine class when you want to mock that class during testing. This is all fine and dandy if the interface can be used as part of multiple classes. However, if the only reason you have an interface is so you can mock this class during testing, then I would call that a language-runtime smell.

If you are never going to use the interface for anything other than mocking, then you are violating both DRY (Don't Repeat Yourself) and YAGNI (You Ain't Gonna Need It). Using interfaces requires synchronizing method signatures between the interface and its classes, thereby violating DRY. If the interface is only used for mocking that class, your are violating YAGNI. DRY and YAGNI reduce your code complexity, making it easier for you to understand your code later (and you always have to understand your code later).

Little Moose Day

Just a short note for the Moose-Pen toady, I am going to clean finish off my Moose droppings by looking at the Expression.

Well all I really have to do is do a search and replace on the word function in my last post and and then past is here but that would be cheating. If I did do that I would at least see if anyone is reading these apart from Gabor.

So I will be working the 14_predicate.t and adding in the following;

my $expression_1_param = {left=> {name=>'left'},
                          right=>{expression => '+',
                                  left       => {name=>'test'},
                                  right  => { param => 3 },
                          }};
eval {
   $predicate =  Database::Accessor::Predicate->new($expression_1_param);
};
 if ($@) {
      fail("expression with 1 param works");
   }
   else {
      pass("expression with 1 param works");
   }

ok(ref($predicate->right) eq 'Database::Accessor::Expression','right is a expression');
and as for the function tests I add in one for multi-params and one for mixed-params but no reason to repeat that here. What I first have to do is have a look at the Expression class

Next stable DBD::SQLite will be released at the end of February

It's been a year since the last stable DBD::SQLite was released. Actually, it's been a year and a half since the SQLite library bundled in the last stable DBD::SQLite was released by the upstream. A lot have happened there, and some here. It's time for you to test them all against your applications/modules, at last.

DBD::SQLite 1.55_07 (with SQLite 3.22.0) is a release candidate of the next stable DBD::SQLite. It has various query planner improvements, optimizations, performance enhancements, and bug fixes, especially on LEFT JOIN queries, IN and OR operators, and WITHOUT ROWID tables. It also supports "row values", that means now you can write a query like this:

UPDATE foo SET (id, text) = (SELECT id, text FROM bar WHERE id = 1);

Follow the links in http://www.sqlite.org/chronology.html, or each of the following links, to see full details.

Moose Show off

Today in the Moose-Pen I am going to cleanup up more Moose droppings. Now I already added in the Function and Expression class and came up with a few modest tests case for them '19_function_expression.t'.

Not that is fine and good for a unit test on that class but the problem is these two classes will never be used as stand alone classes they will always be used inside other objects typically in the same place I would use a Param or Element class and most of the time in a Predicate object.

The best place to basic unit tests of both Function and Expression is in the predicate unit tests case ' 14_predicate.t ' so in there I add firsts added;

my $function_1_param = {left=> {name=>'left'},
                          right=>{function => 'substr',
                                  left       => {name=>'test'},
                                  right  => { param => 3 },
                          }};
ok(Database::Accessor::Predicate->new($function_1_param),"Function with 1 param works");
So in this case the test will fail with this

Attribute (name) is required at C:\D

Lab::Measurement at DPG Spring Meeting in Berlin

The Lab::Measurement module stack will be featured with a poster at Europe's largest physics conference this year, the DPG Frühjahrstagung (Spring Meeting) of the Condensed Matter Section, Berlin, march 11. - 16. 2018.

So please come by on Monday, March 12, 2018, 15:00–19:00, Poster B, TT 29: Poster Session: Cryogenic Particle Detectors and Cyotechnique.

If you cannot wait until march, please consider the Perl in the Physics Lab presentation at FOSDEM by Andreas K. Hüttel, my supervisor, next weekend!

Rakudo.js update - NFG / unicode collation and role bug fixes

Rakudo.js update - NFG, unicode collation and more bugfixes

Rakudo.js has been in bugfixing mode recently.

Rakudo.js now uses NFG (Normal Grapheme Form) semantics in some places.
This means some string operations treat strings as sequences of graphemes instead of unicode code points. Graphemes are "user-perceived characters" (See http://unicode.org/reports/tr29/). This isn't done everywhere yet but it allows us to pass a bunch of roast tests.
Because JavaScript doesn't use graphemes underneath in it's string implementation like MoarVM does using NFG semantics can be much more expensive.
As such in low level setting code we often want to use the native javascript semantics when they are good enough.
To make that a choice I added a bunch of NFG aware op variants like (nqp::charsnfg) so we can pay the price only when it's necessary.

Running Perl for your car's dashboard display

About time!

Moose Delegates

Today in the Moose-Pen I am going to look at something new 'Native Delegations' on attributes or to say it another less wordy way 'Traits'

Native Delegation is a way to let you treat standard Perl data structure as if they where objects. So to take an example from my test cases say you have this

foreach my $index2  (0..(scalar(@{$predicates[$index]->predicates()})-1)) {
that (scalar(@{$predicates[$index]->predicates()})-1)) is not very readable. Now suppose we could just have this

($predicates [$index]->predicates()->count-1)
a little easier to read. Now one can do this kind of thing in plain Perl but it can be a little code gymnastics if you are really interested in how much code it is check out the 'DBD::_::common' package for an example of a partial work up for a Hash object. You can also have a look here to see how to set this up for an ARRAY or if you have trouble falling asleep. There is even a package called Tie::Array

Perl 6 Core Hacking: QASTalicious

Read this article on Rakudo.Party

Over the past month, I spent some time in Rakudo's QAST land writing a few optimizations, fixing bugs involving warnings, as well as squashing a monster hive of 10 thunk scoping bugs with a single commit. In today's article, we'll go over that last feat in detail, as well as learn what QAST is and how to work with it.

PART I: The QAST

"QAST" stands for "Q" Abstract Syntax Tree. The "Q" is there because it's comes after letter "P", and "P" used to be in "PAST" to stand for "Parrot", the name of an earlier, experimental Perl 6 implementation (or rather, its virtual machine). Let's see what QAST is all about!

Dumping QAST

Every Rakudo Perl 6 program compiles down to a tree of QAST nodes and you can dump that tree if you specify --target=ast or --target=optimize command line option to perl6 when compiling a program or a module:

Little Moose Tries to Run

Well more testing and re-factoring with just a little Moose in the Moose-Pen today. So I spend a good deal of time getting my tests cases all in a row. Now just a few interesting details on that, I created a number of generic utility tests that can be reused in my test cases. What I did was take the 'cmp_deeply' test like this on in 33_constants.t

   my $da_conditions  = $da->conditions();
   my $dad_conditions = $dad->Conditions();
   my $in_conditions  = $in_hash2->{conditions};
   foreach my $index (0..scalar(@{$in_conditions}-1)) {
     my $in   = $in_conditions->[$index];
     bless($in,"Database::Accessor::Predicate"); 
     bless($in->{left},"'Database::Accessor::Element"); 
     bless($in->{right},"Database::Accessor::Param"); 
     cmp_deeply($da_conditions->[$index]->predicates->[0], methods(%{$in}),
"DA predicates correct" );
     cmp_deeply($dad_conditions->[$index]->predicates->[0], methods(%{$in}),
"DAD predicates no $index correct" );
      # cmp_deeply( $dad_conditions->predicates->[$index], methods(%{$in}),DAD predicates correct" );
   } 
and converted them into a sub, in this case deep_predicates, then created a packages to hold them ' Test::Database::Accessor::Utils ' and then rather than the above all I call is

Relax it is Just Moose

Well it clean-up and re-factor day in the Moose-pen. So no new Moose Majick today just cleaning up and adding in stuff that I have left out (forgotten actually) and moving things about.

Well the first thing I did was finish off the last three of my remaining Accessor attibutes, 'gathers', 'filters' and 'sort' or if you are SQL inclined 'group by', 'having'. and 'sorts'.

The 'gathers' and 'sorts' attributes are just a pair of 'ArrayRefofElements' which I covered off in this post and types and the 'filters' is a 'ArrayRefofConditions' which I covered in this post. I did of course spend a little time making sure that my DAD role attributes matched up with the accessosr ones and as this is me programming I created two new test cases, 37_gathers.t that handles filters as well, and 39_sorts.t

Low Stress Moose

So today in the Moose-pen I am going to move onto something a little differtn and that is my Accessor 'links' attribute which I am going to cover with the 35_links.t test suite.

I did a quick review of the bits and pieces I had stubbed in so far and I notices I need a few thing. First had a look at my Accessor 'links' attribute and I will need a new type for that. So to get this new 'ArrayRefofLinks' type I just did what we have seen in a number of older posts, namely add in a 'use', a 'class_type' and a 'subtype' into my Types.pm, I will hold off on a coercion for now till I get a little deeper into my post. So that takes case of 'links'.

I also noticed that 'Links' attribute of my DAD now had the wrong type as well so that was change to the 'ArrayRefofLinks' type

Looking at my 'Database::Accessor::Link' class I have never liked this two attributes

Sophisticated Moose

Today in the Moose-pen I am going to play with the very familiar 33_condtions.t and this time I am going to solve another little API problem I know I am going to run into.

Part of my evil plan is to allow end users to add in conditions on the fly and I have made provision for that with the 'rw' 'conditions' attribute found on my DAD Role. Now I have to fix a minor oversight on my part can change the type on 'conditions' to be the same as the original in Accessors, so I changed this

–    isa     => 'ArrayRefofPredicates',
++    isa     => 'ArrayRefofConditions',
 
What I want to be able to do is allow my end users to do something like this

  my $da = Database::Accessor->new($in_hash2);
  $da->DAD->add_condition({left      =>{name =>'country',
                                        view =>'People'},
                           right     =>{value=>'Slyvania'},
                           operator  =>'=',
                           condition =>'AND'});

Late Night Moose

Well in today's Moose-pen I am still going to play about with good old 33_condtions.t , not the tests per-say but the API they are calling. In my last post I fixed the my API call by adding in the 'predicates' param to the 'conditions' param like this

...
 view =>'People' } ],
conditions=>[{predicates=>[{left=>{name =>'last_name',
                                   view =>'People'},
...         
to me the above is a little wordy an error prone. The original API call I attempted

…
      view =>'People' } ],
  conditions=>[{left =>{name =>'last_name',
                        view =>'People'},...
in this post was nicer. Now how to achieve that??

Well I could use 'around BUILDARGS' call like I did for various 'read' and 'write' flags from this post. With the 'around' I could then manipulate what is coming and return what I want. Now the problem with that is I would get no class level re-use from it. Each class that used the same pattern or in this case type of 'ArrayRefofConditions', would require it own 'around' clause.

Call for Presenters TPCiSLC 2018

Talk submissions for #TPCiSLC are currently being accepted! Round 1 closing/Round 2 opening Jan 28/29.

We will be accepting proposals for the following session types:

Short Talks (20 minutes)
Standard Talks (50 minutes)
Tutorial Sessions (80 or 110 minutes)

To submit proposals for a talk/presentation, please fill out this form: https://goo.gl/forms/2qxdfgtRsdc6lXBZ2.

We encourage you to submit your talk as early as possible. We will be choosing speakers in an ongoing process, with the final submissions to be accepted no later than March 18th, 2018.

Round 1: January 1st - January 28th, speakers notified by 2/7/18
Round 2: January 29th - February 25th, speakers notified by 3/7/18
Round 3: February 26th - March 18th, speakers notified by 3/28/18
Final Speaker Lineup Announced: April 1st, 2018

Apply at https://goo.gl/forms/2qxdfgtRsdc6lXBZ2

More information at https://perlconference.us/tpc-2018-slc/cfp/

Not a Mousse Moose!

So in my last Moose-pen I ran into problem with my 33_conditions.t test case where it was giving me errors like this

# Compared $data->left # got : Does not exist …
Well after some playing about I saw the errors of my ways. Looking at the Database::Accessor::Condition class I remembered to load that properly I will have to pass in any conditions with the 'predicates' param. So I modified my$$in_hash to this;

 conditions=>[{predicates=>[{left=>{name=>'last_name',
                                    view=>'People'},
                             right=>{ param=>'test'},
                             operator=>'='
                             },
                             {condition=>'AND',
                                   left=>{name=>'first_name',
                                          view=>'People'},
                                  right=>{ param=>'test'},
                               operator=>'='}]}],
I ran my test again but then I was back at square one again?
Attribute (name) is required at C:\Dwimperl\perl\site\lib\Moose\Object.pm line 24 Moose::Object::new('Database::Accessor::Element', 'param', 'test') called at D:\GitHub\database-accessor\lib\Database\Accessor\Types.pm line 29
Hmm... So it looks like it does not like my 'param' coercion again. I double checked my 'Database::Accessor::Predicate' class and saw that I had

Just A Cute Moose

Well today in the Moose-pen I am still going to have a look at my 33_conditions.t test case. In my last post I got all the little bits working right up to the point when I want the DAD to return or at least crate this string

RETRIEVE-->View-->'People'-->Elements-->'People.first_name',
'People.last_name','People.user_id'-->Condtion->People.user_id=test-->AND-->
People.first_name=John

After sleeping on it and then playing a bit I came to the very wise conclusion to not to test my Accessor in this way. If I take this path then I am opening myself up to going down all sorts of test rabbit holes where there is nothing wrong with my Accessor but a problem in my Tests DAD. So what to do?

Well lets have a look at what I have to test:

  • coercion from a hash to a type works correctly
  • class attribute values passed into the DAD are correct

Best Moose Opening Line Ever

So today in the Moose-Pen I was going to get my 33_conditions.t test case working. New we left off in my last post with this call to Accessor

my $user = Database::Accessor->new(
    {
        view     => {name  => 'People'},
        elements => [{ name => 'first_name',
                                 view=>'People' },
                             { name => 'last_name',
                                view => 'People' },
                             { name => 'user_id',
                                view =>'People' } ],
        conditions=>[{ left=>{name=>'user_id',
                               view=>'People'},
                               operator=>'=',
                               right=>{param=>'test'}},
                               { condition=>'AND',
                                   left=>{name=>'first_name',
                                             view=>'People'},
                                  operator=>'=',
                                 right=>{param=>'John'}},  ]
    }
);
which in SQL is

SELECT People.first_name,People.last_name, People.user_id 
  FROM People
 WHERE  People.user_id = 'test'
   AND  People.first_name = 'John'
and Mongo something like this

  db.People.find({$and: [{user_id: {$eq: test}},{user_id: {$eq: John}}]},{ street: 1, city: 1, country: 1}
Not I do not have a working Mongo or SQL DAD right not so the above are just for show so I have to use my fudged results from my last post with my Test::DAD. So I am looking to get this

RETRIEVE-->View-->'People'-->Elements-->'People.first_name',
'People.last_name','People.user_id'-->Condtion->People.user_id=test-->AND-->
People.first_name=John

Less Moose more Elk

Well back to clean up mode in the old Moose-pen today as I have completed my first round of changes to my Database::Accessor embedded classes. Just taking a quick peed at what might attributes might be missing from my I see that my Predicate is missing something important at least to any logical predicate. That is the ability to add parentheses to a predicate.

Well the way I see it I can just make this a Boolean flag attributes such as 'parentheses' but that takes a good deal of flexibility from the system. So what I am going to go for is two flags one for open and one from close, like this

   has open_parentheses => (
      is  => 'rw',
      isa => 'Bool',
      default => 0,
      alias    => [qw(open open_paren)]
    );

    has close_ parentheses  => (
      is  => 'rw',
      isa => 'Bool',
      default => 0,
      alias    => [qw(close close_paren)]
    );

About blogs.perl.org

blogs.perl.org is a common blogging platform for the Perl community. Written in Perl and offering the modern features you’ve come to expect in blog platforms, the site is hosted by Dave Cross and Aaron Crane, with a design donated by Six Apart, Ltd.