Need help with properties

108 views
Skip to first unread message

Dan Jones

unread,
Aug 28, 2014, 3:29:54 PM8/28/14
to haxe...@googlegroups.com
I'm just starting to learn Haxe, so I apologize if this is obvious (although Google yielded no answers for me).

I'm using Haxe, with a Neko target, to build an application that interacts with a Calibre (sqlite) database.

I have a class definition that looks like this:
@:table("books")
class Book extends sys.db.Object {
    public var id: SId;
    public var title: SText;
    public var sort: SNull<SText>;
    public var timestamp: STimeStamp;
    public var pubdate: STimeStamp;
    public var series_index: SFloat;
    public var author_sort: SNull<SText>;
    public var isbn: SText;
    public var lccn: SText;
    public var path: SText;
    public var flags: SInt;
    public var uuid: SNull<SText>;
    public var has_cover: SBool;
    public var last_modified: STimeStamp;
    
    @:skip public var name(get,never):String;
    
    public function get_name():String {
        return title + ' by ' + getAuthors().join(' & ');
    }
    
    override public function toString() {
        return name;
    }

    public function getAuthors() :Array<Author> {
        ...
    }

    ...
}

Elsewhere, I have something like this:
trace(the_book);
trace(the_book.get_name());
trace(the_book.title);

And I'm getting a result like this:
LibraryBrowser.hx:165: Youth by Isaac Asimov
LibraryBrowser.hx:166: null
LibraryBrowser.hx:167: Youth by Isaac Asimov
LibraryBrowser.hx:168: Youth

So, the getter function works, but the property (name) does not. I can't, for the life of me, figure out what I'm doing wrong.
The property works from within the class (since toString simply returns name), but outside the class, it's only null.

Any ideas?

Simon Krajewski

unread,
Aug 28, 2014, 11:50:35 PM8/28/14
to haxe...@googlegroups.com

What type does the_book have? Properties only work if the field access is made on a proper type, else the compiler cannot resolve the accessors.

Simon

--
To post to this group haxe...@googlegroups.com
http://groups.google.com/group/haxelang?hl=en
---
You received this message because you are subscribed to the Google Groups "Haxe" group.
For more options, visit https://groups.google.com/d/optout.

Dan Jones

unread,
Aug 29, 2014, 12:18:21 AM8/29/14
to haxe...@googlegroups.com
the_book is an instance of the Book class. $type says it's Unknown<0>. I'm not sure what that means.

Yaroslav Sivakov

unread,
Aug 29, 2014, 3:55:24 AM8/29/14
to haxe...@googlegroups.com
Simon is right. Looks like compiler does nopt know type of "the_book". Try to specify type directly:

var the_book : Book = getTheBook();



Simon Krajewski

unread,
Aug 29, 2014, 3:57:47 AM8/29/14
to haxe...@googlegroups.com

That seems weird though, could you post the related code so we can see what's going on?

Simon

On 29 Aug 2014 09:55, "Yaroslav Sivakov" <yar...@gmail.com> wrote:
Simon is right. Looks like compiler does nopt know type of "the_book". Try to specify type directly:

var the_book : Book = getTheBook();



Dan Jones

unread,
Aug 29, 2014, 8:53:54 AM8/29/14
to haxe...@googlegroups.com
That was it!

I had var the_book = all_the_books[i] where all_the_books was an Array<Book>.

I changed that to var the_book:Book = all_the_books[i] and it worked as expected.

Thanks so much. I guess I'm way too used to loosely-typed languages. I did some Java and C# in college, but since then I'm been only PHP and Python, so I guess I've gotten a little sloppy in that area.

Dan Jones


On Fri, Aug 29, 2014 at 3:55 AM, Yaroslav Sivakov <yar...@gmail.com> wrote:
Simon is right. Looks like compiler does nopt know type of "the_book". Try to specify type directly:

var the_book : Book = getTheBook();



You received this message because you are subscribed to a topic in the Google Groups "Haxe" group.

Dan Korostelev

unread,
Aug 29, 2014, 9:00:07 AM8/29/14
to haxe...@googlegroups.com
That is strange. If your all_the_books really is Array<Book>, the Book type should be inferred correctly.

пятница, 29 августа 2014 г., 16:53:54 UTC+4 пользователь Dan Jones написал:

Simon Krajewski

unread,
Aug 29, 2014, 9:07:58 AM8/29/14
to haxe...@googlegroups.com

Indeed, could you post some code that reproduces the behavior?

Simon

You received this message because you are subscribed to the Google Groups "Haxe" group.

Dan Jones

unread,
Aug 29, 2014, 9:24:50 AM8/29/14
to haxe...@googlegroups.com
In addition to the code already posted, I have this other class:
@:table("authors")
@:index(link,unique)
class Author extends sys.db.Object {
    public var id: SId;
    public var name: SText;
    public var sort: SNull<SText>;
    public var link: SText;
    
    override public function toString() {
        return name;
    }
    
    public function getBooks() :Array<Book> {
        ...
    }
    ...
}

And right above the problem code, I have this:
var id = Std.parseInt(args[0]); // args is an Array<String>
var the_author = if (id == null) Author.manager.get(1) else Author.manager.get(id);
var all_the_books = new Array<Book>(); the_books = the_author.getBooks();

That second line should probably have book var all_the_books:Array<Book> = the_author.getBooks();
I should probably get more used to declaring the type every time, instead of depending on type inference.

Dan Jones

Dan Korostelev

unread,
Aug 29, 2014, 10:13:11 AM8/29/14
to haxe...@googlegroups.com
Actually, declaring type every time is uncool and boring and should only be needed in complicated cases :-) Cases when you need to declare a type for a local variable should be rare.
However I do explicitly type function arguments and return value.

пятница, 29 августа 2014 г., 17:24:50 UTC+4 пользователь Dan Jones написал:

Dan Korostelev

unread,
Aug 29, 2014, 10:14:36 AM8/29/14
to haxe...@googlegroups.com
Maybe the_author is a mononmorph (Unknown) there? Could you do $type(the_author) and see what haxe prints when compiling?

пятница, 29 августа 2014 г., 17:24:50 UTC+4 пользователь Dan Jones написал:

Dan Jones

unread,
Aug 29, 2014, 10:25:41 AM8/29/14
to haxe...@googlegroups.com
Nope. the_author is an Author, which is what you would expect. Author.manager.get should always return an Author, I would assume.

It's no big deal. Explicitly declaring the_book as a Book fixed the problem anyway.

Dan Jones
Message has been deleted

Simon Krajewski

unread,
Aug 29, 2014, 10:30:00 AM8/29/14
to haxe...@googlegroups.com

@nadako: can you file an issue if you can reproduce?

Simon

Ma rk

unread,
Aug 29, 2014, 10:30:14 AM8/29/14
to haxe...@googlegroups.com
[Player 3 joined the game]

I'm sorry but I disagree with you. I think it is a very good idea to declare type (and initialize) all and every variables.
There might be a guy one day who tries to understand that code and it's a lot of help. That guy can be the same one who wrote the code years before that time :)

Simon Krajewski

unread,
Aug 29, 2014, 10:31:10 AM8/29/14
to haxe...@googlegroups.com

Yes but in cases like var x = 1 it is utterly redundant.

Simon

On 29 Aug 2014 16:29, "Ma rk" <markk...@gmail.com> wrote:
[Player 3 joined the game]

I'm sorry but I disagree with you. I think it is a very good idea to declare (and initialize) all and every variables.

There might be a guy one day who tries to understand that code and it's a lot of help. That guy can be the same one who wrote the code years before that time :)



On Friday, August 29, 2014 4:13:11 PM UTC+2, Dan Korostelev wrote:

--

Dan Korostelev

unread,
Aug 29, 2014, 10:33:25 AM8/29/14
to haxe...@googlegroups.com
Don't really want to start this discussion, but IMO "var booksByTitle:Map<String,Book> = new Map<String,Book>()" is too much :)

Actually, I wrote some of my reasons in a post a few months ago: http://nadako.tumblr.com/post/79958903007/on-my-haxe-coding-style

пятница, 29 августа 2014 г., 18:30:14 UTC+4 пользователь Ma rk написал:

Dan Korostelev

unread,
Aug 29, 2014, 10:33:47 AM8/29/14
to haxe...@googlegroups.com
Nope, I can't reproduce that :)

пятница, 29 августа 2014 г., 18:30:00 UTC+4 пользователь Simon Krajewski написал:

Dan Jones

unread,
Aug 29, 2014, 5:34:37 PM8/29/14
to haxe...@googlegroups.com
Turns out that only fixed half the problem.
the_book.name isn't available from within a template.
I have a short template like this:
<entry><title>::book.name::</title></entry>

The template is being called like this:
var out = template.execute({book:the_book});
Sys.print(out);

But it prints out like this: <entry><title>null</title></entry>

If I change the template call to this: var out = template.execute({book:the_book, name: the_book.name}) and the template to <entry><title>::name::</title></entry>, I get the expected results. So the_book.name is accessible from within the code, but not the template.

Do templates not have access to properties, if there's no physical field?

Cristian Baluta

unread,
Aug 30, 2014, 1:06:34 AM8/30/14
to haxe...@googlegroups.com
Player 4

If the method is not clear about what is returning i declare the type myself when i call it. Ex: var ViewerClass :Class<Dynamic> = Type.resolveClass ( viewerType );

On the other hand: var viewerType = Preferences.stringForKey("viewer");

Both from a software I wrote years ago.


You received this message because you are subscribed to the Google Groups "Haxe" group.

For more options, visit https://groups.google.com/d/optout.



--

Dan Jones

unread,
Sep 2, 2014, 1:11:48 AM9/2/14
to haxe...@googlegroups.com
Turns out that only fixed half the problem.
the_book.name isn't available from within a template.
I have a short template like this:
<entry><title>::book.name::</title></entry>

The template is being called like this:
var out = template.execute({book:the_book});
Sys.print(out);

But it prints out like this: <entry><title>null</title></entry>

If I change the template call to this: var out = template.execute({book:the_book, name: the_book.name}) and the template to <entry><title>::name::</title></entry>, I get the expected results. So the_book.name is accessible from within the code, but not the template.

Do templates not have access to properties, if there's no physical field?

Dan Jones

Simon Krajewski

unread,
Sep 2, 2014, 1:14:43 AM9/2/14
to haxe...@googlegroups.com
Am 29.08.2014 18:01, schrieb Dan Jones:
Turns out that only fixed half the problem.
the_book.name isn't available from within a template.
I have a short template like this:
<entry><title>::book.name::</title></entry>

The template is being called like this:
var out = template.execute({book:the_book});
Sys.print(out);

But it prints out like this: <entry><title>null</title></entry>

If I change the template call to this: var out = template.execute({book:the_book, name: the_book.name}) and the template to <entry><title>::name::</title></entry>, I get the expected results. So the_book.name is accessible from within the code, but not the template.

Do templates not have access to properties, if there's no physical field?

Templates typically resolve fields at runtime using Reflect.field, which does not respect properties. You can try subclassing haxe.Template and override its resolve method to use Reflect.getProperty instead.

Simon
Reply all
Reply to author
Forward
0 new messages