I have this one question, about Lua metatables. I heard and looked them up, but I don't understand how to use them and for what.
metatables are functions that are called under certain conditions.
Take the metatable index "__newindex" (two underscores), when you assign a function to this, that function will be called when ever you add a new index to a table, like;
table['wut'] = 'lol';
this is an example of a custom metatable using '__newindex'.
ATable = {}
setmetatable(ATable, {__newindex = function(t,k,v)
print("Attention! Index \"" .. k .. "\" now contains the value \'" .. v .. "\' in " .. tostring(t));
end});
ATable["Hey"]="Dog";
the output:
Attention! Index "Hey" now contains the value 'Dog' in table: 0022B000
metatables can also be used to describe how Tables should interact with other Tables, and different values.
This is a list of all the possible metatable indexes you can use
* __index(object, key) -- Index access "table[key]".
* __newindex(object, key, value) -- Index assignment "table[key] = value".
* __call(object, arg) -- called when Lua calls the object. arg is the argument passed.
* __len(object) -- The # length of operator.
* __concat(object1, object2) -- The .. concatination operator.
* __eq(object1, object2) -- The == equal to operator.
* __lt(object1, object2) -- The < less than operator.
* __le(object1, object2) -- The <= less than or equal to operator.
* __unm(object) -- The unary - operator.
* __add(object1, object2) -- The + addition operator.
* __sub(object1, object2) -- The - subtraction operator. Acts similar to __add.
* __mul(object1, object2) -- The * mulitplication operator. Acts similar to __add.
* __div(object1, object2) -- The / division operator. Acts similar to __add.
* __mod(object1, object2) -- The % modulus operator. Acts similar to __add.
* __tostring(object) -- Not a proper metamethod. Will return whatever you want it to return.
* __metatable -- if present, locks the metatable so getmetatable will return this instead of the metatable and setmetatable will error.
I hope this clears things up, if you need a few more examples, click here.
They allow tables to be treated like other types such as string, functions, numbers etc.
For a high level, entertaining read on the prototype pattern check out http://steve-yegge.blogspot.com/2008/10/universal-design-pattern.html. This may help you with the 'what'.
Related
I've been stuck on a GORM issue for about a full day now. I need to be able to filter a messages table on any of 4 things: sender, recipient, keyword, and date range. It also has to paginate. Filtering by sender and recipient is working, and so is pagination. So far this is the query that I have come up with, but it does not seem to work for date ranges or keywords.
Here is how I am selecting from MySQL
db.Preload("Thread").Where(query).Scopes(Paginate(r)).Find(&threadMessages)
I am creating the query like this:
var query map[string]interface{}
Then based on which parameters I am passed, I update the query like this by adding new key values to the map:
query = map[string]interface{}{"user_id": sender, "recipient_id": recipient}
For dates it does not seem to work if I try something like this:
query = map[string]interface{}{"created_at > ?": fromDate}
And for a LIKE condition is also does not seem to work:
query = map[string]interface{}{"contents LIKE ?": keyword}
The reason I chose this approach is that I could not seem to get optional inputs to work in .Where since it takes a string with positional parameters and null positional parameters seem to cause MySQL to return an empty array. Has anyone else dealt with a complicated GORM issue like this? Any help is appreciated at this point.
Passing the map[string]interface{} into Where() only appears to work for Equals operations, or IN operations (if a slice is provided as the value instead).
One way to achieve what you want, is to construct a slice of clause.Expression, and append clauses to the slice when you need to. Then, you can simply pass in all of the clauses (using the ... operator to pass in the whole slice) into db.Clauses().
clauses := make([]clause.Expression, 0)
if mustFilterCreatedAt {
clauses = append(clauses, clause.Gt{Column: "created_at", fromDate})
}
if mustFilterContents {
clauses = append(clauses, clause.Like{Column: "contents", Value: keyword})
}
db.Preload("Thread").Clauses(clauses...).Scopes(Paginate(r)).Find(&threadMessages)
Note: If you're trying to search for content that contains keyword, then you should concatenate the wildcard % onto the ends of keyword, otherwise LIKE behaves essentially the same as =:
clause.Like{Column: "contents", Value: "%" + keyword + "%"}
My final solution to this was to create dynamic Where clauses based on which query params were sent from the client like this:
fields := []string{""}
values := []interface{}{}
If, for example, there is a keyword param:
fields = []string{"thread_messages.contents LIKE ?"}
values = []interface{}{"%" + keyword + "%"}
And to use the dynamic clauses in the below query:
db.Preload("Thread", "agency_id = ?", agencyID).Preload("Thread.ThreadUsers", "agency_id = ?", agencyID).Joins("JOIN threads on thread_messages.thread_id = threads.id").Where("threads.agency_id = ?", agencyID).Where(strings.Join(fields, " AND "), values...).Scopes(PaginateMessages(r)).Find(&threadMessages)
Say you need to store the name of all local variables in a script: local = union(who,"local"). Is there a function to replace the name ("local") with a reference to the variable which is to the left of the expression?
Update: For the sake of clarity, the sentence will be rewritten like local = union(who, leftside()), where the leftside function returns local.
Is there a sort of leftside() function with this behavior?
Do you mean like this?
>> a = "test"
a = test
>> b = "rest "
b = rest
>> a = union(b, a)
a = erst
>> help union
'union' is a function from the file C:\Octave\Octave-4.0.3\share\octave\4.0
.3\m\set\union.m
-- Function File: C = union (A, B)
-- Function File: C = union (A, B, "rows")
-- Function File: [C, IA, IB] = union (...)
Return the unique elements that are in either A or B sorted in
ascending order.
Update:
I'm not aware of such function. There are bunch of built in functions for internal use, that have the names like __func_name__ and you may get a list of them if you type __ in the Octave's command window and press tab twice. At a glance I don't think there is a function, like the one you need, but take a more detailed look if you like.
Can you describe why do you need such behavior, maybe there is a different approach that can suit your needs i.e there are functions for programmatic creation of variables - genvarname.
Following a minimal example of an observation (that kind of astonished me):
type Vector = V of float*float
// complete unfolding of type is OK
let projX (V (a,_)) = a
// also works
let projX' x =
match x with
| V (a, _) -> a
// BUT:
// partial unfolding is not Ok
let projX'' (V x) = fst x
// consequently also doesn't work
let projX''' x =
match x with
| V y -> fst y
What is the reason that makes it impossible to match against a partially deconstructed type?
Some partial deconstructions seem to be ok:
// Works
let f (x,y) = fst y
EDIT:
Ok, I now understand the "technical" reason of the behavior described (Thanks for your answers & comments). However, I think that language wise, this behavior feels a bit "unnatural" compared to rest of the language:
"Algebraically", to me, it seems strange to distinguish a type "t" from the type "(t)". Brackets (in this context) are used for giving precedence like e.g. in "(t * s) * r" vs "t * (s * r)". Also fsi answers accordingly, whether I send
type Vector = (int * int)
or
type Vector = int * int
to fsi, the answer is always
type Vector = int * int
Given those observations, one concludes that "int * int" and "(int * int)" denote exactly the same types and thus that all occurrences of one could in any piece of code be replaced with the other (ref. transparency)... which as we have seen is not true.
Further it seems significant that in order to explain the behavior at hand, we had to resort to talk about "how some code looks like after compilation" rather than about semantic properties of the language which imo indicates that there are some "tensions" between language semantics an what the compiler actually does.
In F#
type Vector = V of float*float
is just a degenerated union (you can see that by hovering it in Visual Studio), so it's equivalent to:
type Vector =
| V of float*float
The part after of creates two anonymous fields (as described in F# reference) and a constructor accepting two parameters of type float.
If you define
type Vector2 =
| V2 of (float*float)
there's only one anonymous field which is a tuple of floats and a constructor with a single parameter. As it was pointed out in the comment, you can use Vector2 to do desired pattern matching.
After all of that, it may seem illogical that following code works:
let argsTuple = (1., 1.)
let v1 = V argsTuple
However, if you take into account that there's a hidden pattern matching, everything should be clear.
EDIT:
F# language spec (p 122) states clearly that parenthesis matter in union definitions:
Parentheses are significant in union definitions. Thus, the following two definitions differ:
type CType = C of int * int
type CType = C of (int * int)
The lack of parentheses in the first example indicates that the union case takes two arguments. The parentheses
in the second example indicate that the union case takes one argument that is a first-class tuple value.
I think that such behavior is consistent with the fact that you can define more complex patterns at the definition of a union, e.g.:
type Move =
| M of (int * int) * (int * int)
Being able to use union with multiple arguments also makes much sense, especially in interop situation, when using tuples is cumbersome.
The other thing that you used:
type Vector = int * int
is a type abbreviation which simply gives a name to a certain type. Placing parenthesis around int * int does not make a difference because those parenthesis will be treated as grouping parenthesis.
When a reader starts to read the function code, he should already have a very good idea of what it is does, how it does it, and what problems he might meet. I'm trying to write clean, structured, well-commented code that is easy to understand. And I'm reading Ada Style Guide and some things I didn't understand well enough, what can i write for optional sections (for exapmle: #Error_Handling, #Pre, #Post).
I want to represent this Function like an example. Using the above guidelines, a standard function header may be derived:
-- ---------------------------------------------------------------------------
-- #Function: Arithmetic_Mean
--
-- #Description:
-- Function to find the mean of a numeric vector. The program should
-- work on a zero-length vector (with an answer of 0.0).
-- #Usage: (opt)
-- #Parameter:
-- +Num: Given array
-- #Return: Averages/Arithmetic mean or zero
-- #Error_Handling: (opt)
-- #Pre: (opt)
-- #Post (opt)
type Mean_Numbers is array (Natural range <>) of Float;
function Arithmetic_Mean (Num : Mean_Numbers) return Float is
Sum : Float := 0.0;
begin
if Num'Length > 0 then
while Num'First <= Num'Last loop
Sum := Sum + Num(Num'First );
end loop;
return Sum / Float (Num'Length);
end if;
return 0.0;
end Arithmetic_Mean;
And here is another example:
-------------------------------------------------------------- ... --
-- #Function: Get_Index
-- #Description:
-- Returns the minimum index of Item in A.
-- #Parameters:
-- +A: the array
-- +Item: element searched for
-- #Return:
-- The minimum index of Item in A.
-- #Pre:
-- true
-- #Post:
-- if exists 1 <= I <= UPPER_BOUND: A(I) = Item then
-- result = min {1 <= k <= UPPER_BOUND | a(j) = item }
-- else
-- result = 0
The #Pre and #Post tags should document your module's approach to Design by Contract. As you observed, any precondition must be true for successful execution, and any postcondition is a promise to be fulfilled by your code. The #Error_Handling tag identifies how you deal with violations of the other two.
As a concrete example, your implementation of Arithmetic_Mean silently ignores an empty input array, returning a mean of zero; it propagates any exceptions that are raised. These are the behaviors that should be documented.
Several benefits accrue:
The API programmer can clearly state the intended behavior.
The API client can distinguish among possible sources of error.
A reviewer can verify whether the intention matches the implementation.
See also Introduction to Ada: Design by contracts, which illustrates Ada 2012 support for enforcing contracts. The Rationale for Ada 2012 offers an overview of the topic and related aspects.
I am trying to query a database. I already have a file that includes some primary keys out of this whole database. Now I want to filter these primary keys and get only those primary keys which also agree to "other condition". My primary keys are associated to abstracts in the database. The abstracts are full-text indexed. Now I want to consider the abstracts using the given primary keys, look for my "other condition(terms)" in those abstracts and if its present I want to pull their primary keys out(which is going to be same from the file). My "other condition" is another file with a list of terms. I want to get the abstracts that contain those terms within the given primary keys.
My full-text search is something like this:
while(<FILE1>){
$PK = $_;
foreach $foo(#foo){
my $sth = $dbh->prepare(qq{
SELECT value
FROM value_table
WHERE MATCH (column_text_indexed) AGAINST (? IN BOOLEAN MODE)
}) AND primary_key=$PK;
$sth->execute(qq{+"$foo"});
}
}
where $PK is coming from the list of primary keys I already have.
$foo will be the list of the terms (condition 2) I am looking for.
Normally, I can run this query number of $PK times number of $foo. But I learned something about optimization by sub querying where I won't be running my query # $PK times # $foo. That will get rid of inner loop but will still form combination of every $PK with every term in file 2 that is #foo. Something like as follows:
while(<FILE1>){
$PK = $_;
my $sth = $dbh->prepare(qq{
SELECT value
FROM value_table
WHERE MATCH (column_text_indexed) AGAINST (**SUB QUERYING HERE**)
}) AND primary_key=$PK;
$sth->execute(qq{+"$foo"});
}
Just I don't know how to do it. I may be wrong with the syntax. I want to know how to write code for full-text search as well as a subquery. I hope this will be efficient than querying directly the combinations. Any help is greatly appreciated.
I don't think you need to use a subquery. But you can still get rid of the inner loop by combining the match strings.
my $against = join ' ', map {qq/"$_"/} #foo;
while (my $PK = <FILE1>) {
chomp $PK;
my $sth = $dbh->prepare(qq{
SELECT value
FROM value_table
WHERE primary_key = ?
# no '+' so it can match against at least one of the words in the list
AND MATCH (column_text_indexed) AGAINST (? IN BOOLEAN MODE)
});
$sth->execute($PK, $against);
Update
I revised it and have completely removed the query from the loops.
my #primary_keys;
while (my $PK = <FILE1>) {
chomp $PK;
push #primary_keys, $PK;
}
my $PK_list = join ',', map {qq/'$_'/} #primary_keys;
my $against = join ' ', map {qq/"$_"/} #foo;
my $sth = $dbh->prepare(qq{
SELECT value
FROM value_table
# placeholders can only represent single scalar values so $PK_list can't be bound
WHERE primary_key IN ($PK_list)
# no '+' so it can match against at least one of the words in the list
AND MATCH (column_text_indexed) AGAINST (? IN BOOLEAN MODE)
});
$sth->execute($against);
# continue with fetching the rows
...;
Your syntax looks dodgy. I think you meant:
while(<FILE1>){
$PK = $_;
foreach $foo (#foo){
my $sth = $dbh->prepare(qq{
SELECT value
FROM value_table
WHERE MATCH (column_text_indexed)
AGAINST (**SUB QUERYING HERE**)
AND primary_key=$PK }); # '})' after AND clause
$sth->execute(qq{ $foo });
}
}
But why not make $PK an additional argument in this case (and use best practices)? :
while ( my $PK = <FILE1> ) {
chomp $PK; # Remove trailing newline
foreach my $foo ( #foo ) { # Lexical $foo
my $sth = $dbh->prepare( qq{
SELECT value
FROM value_table
WHERE MATCH (column_text_indexed)
AGAINST (**SUB QUERYING HERE**)
AND primary_key=? }); # Extra placeholder
$sth->execute( $foo, $PK );
}
}
If you want efficiency I would recommend to use least database transactions and operations. So in this case I think the best option is to just get the abstract from the database based the primary key and then search for the terms in that abstract by doing simple string search in your pearl or any other standard language code. I am not very sure of the length of your list of terms. But if its possible you can save it in a standard data-structure like array or list. The same operation in database would definitely take lot more time. I am not that good with pearl syntax so I am writing the algorithm.
for all the terms in PK get the abstract as a string variable :
for each term in array/list: find the term in string variable containing abstract. If found add the PK to a new file.
continue with next pk.
if not found then continue next term in array/list.