rohitpaulk has quit [Remote host closed the connection]
DTZUZO has joined #crystal-lang
hightower2 has joined #crystal-lang
early has quit [Quit: Leaving]
early has joined #crystal-lang
_whitelogger has joined #crystal-lang
_whitelogger has joined #crystal-lang
_whitelogger has joined #crystal-lang
_whitelogger has joined #crystal-lang
_whitelogger has joined #crystal-lang
waheedi has joined #crystal-lang
ashirase has quit [Ping timeout: 258 seconds]
ashirase has joined #crystal-lang
mwlang has joined #crystal-lang
<mwlang>
Hello. I’m a long-time Ruby developer giving Crystal a whirl. I am trying to set up a property on a class that is of type “Bollinger” which is a class as well. https://gist.github.com/mwlang/daa20e2ffda42ce9a35ccb1faf20f8a9 The error I’m getting, even though I’m clearly initializing the instance variable in the initialization method is : “instance variable '@bollinger' of Trend was not initialized directly in all
<mwlang>
the 'initialize' methods, rendering it nilable. Indirect initialization is not supported.”
<mwlang>
what is indirect about this line/assignment statement? “@bollinger = Bollinger.new(self, {period_multiplier: @period_multiplier * 7.5})”
<jokke>
hey
<jokke>
does shards.yml support expanding env vars?
alex```13685558 has joined #crystal-lang
alex```1368555 has quit [Ping timeout: 246 seconds]
<FromGitter>
<mwlang> This looks like a more happening place than IRC. @j8r I wasn't sure if alerting you from IRC side worked, so logged into gitter to continue conversation.
<FromGitter>
<tenebrousedge> @mwlang why are you passing `self` to `Bollinger.new`?
<FromGitter>
<mwlang> Intent is for Trend to hold many calculations and Bollinger will need to refer to them.
<FromGitter>
<mwlang> right now, it's just simplified enough to get started and reflect the error I'm experiencing.
mwlang has quit [Quit: mwlang]
<FromGitter>
<mwlang> I just fixed omission of the "trend" parameter in the play example, but still same error experienced.
<FromGitter>
<j8r> @mwlang you use `self` at line 18, but self isn't yet fully initialized
<FromGitter>
<tenebrousedge> I think maybe you might write `def bollinger; @bollinger ||= Bollinger.new(self); end`
<FromGitter>
<mwlang> @j8r The simplified version would be enough if I wasn't using the Trend class as essentially a holder of "global values" For example, in current implementation, I'm only referencing @max_size to do bollinger's computation, but end-goal, I will calculate optimal size to compute bollinger for in the trend using another class. When bollinger is called to calculate, it'll reference it's @trend.optimal_size instead
<FromGitter>
... of @max_size.
<FromGitter>
<mwlang> Trend is basically a class that will model stock market tickers.
<FromGitter>
<mwlang> @tenebrousedge I also tried that... updated the play again, attempting to set @bollinger before first time reference. That definitely leads to an indirect initialization error: "instance variable '@bollinger' of Trend was not initialized directly in all of the 'initialize' methods, rendering it nilable. Indirect initialization is not supported."
<FromGitter>
<mwlang> and if I remove the getter bollinger line from that, I get" "Error: 'self' was used before initializing instance variable '@bollinger', rendering it nilable" even though the #push call comes distinctly after Trend has been completely initialized.
<FromGitter>
<tenebrousedge> link to that version?
<FromGitter>
<mwlang> interesting. so basically clever coding to skip past a compiler check.
<FromGitter>
<tenebrousedge> I'd just use a separate method and consider it a property that doesn't need to be initialized until the first call
<FromGitter>
<tenebrousedge> but I would also think about whether the overall structure makes sense. In particular, whether `optimal_size` is really a property of `Trend`
<FromGitter>
<mwlang> It makes sense with overall picture. Assets have trends and trends have different "trends" (or indicators, really) such as bollinger, rsi, etc.
<FromGitter>
<mwlang> just performed metrics on 140,000 data points comparing Crystal computing bollinger bands and Ruby computing same. Crystal took 1m54.025s while Ruby took 9m13.247s
<FromGitter>
<j8r> you compiled in release?
<FromGitter>
<mwlang> I can try that now...that was just normal build.
<FromGitter>
<mwlang> hold on...need to pick myself up off the floor --- fell outta my chair. with --release flag added, crystal just did same test in 18.097s
<FromGitter>
<j8r> Right, this sounds more correct :P
<FromGitter>
<mwlang> ok, I'm sold. :-D
<FromGitter>
<j8r> only 4x looked a bit too low
<FromGitter>
<j8r> `getter bollinger : Bollinger { Bollinger.new(self) }` (or with do...end) is a syntax for memoization, it does something equivalent to `||=`
<FromGitter>
<j8r> @mwlang have also measured the memory used?
<FromGitter>
<mwlang> Not yet. I primarily wanted to see what just the simplest of indicators I could reimplement in Crystal would do
<FromGitter>
<mwlang> main problem I have with Ruby is processing live streamed data on 100's of assets -- I've pushed the limits of how fast I can do it with Ruby
<FromGitter>
<mwlang> with threading, redis, and other hacks to break up and scale.
<FromGitter>
<mwlang> it's either throw a lot more hardware at the problem and get into even more micro-services or look at later more suitable languages.
<FromGitter>
<yxhuvud> There are ways around the passing self in initialize (by using `uninitialized`), but I'd recommend refactoring - that particular pattern doesn't translate well.
<FromGitter>
<mwlang> I'm realizing that pattern doesn't translate well. I'm thinking to have a separate struct/class that holds the variables trend is currently holding and pass that structure to all the various indicators.
<FromGitter>
<mwlang> trend updates the values of this new struct and the indicators can access the updated values as needed.
<FromGitter>
<mwlang> then I don't have to pass the trend object itself when initializing indicators.
<FromGitter>
<j8r> note that struct are passed by reference
<FromGitter>
<yxhuvud> @j8r: No. They are passed by value.
<FromGitter>
<yxhuvud> (as opposed to regular objects)
<FromGitter>
<j8r> yes I meant class by reerence and struct by value
<FromGitter>
<j8r> I miss typed
<FromGitter>
<mwlang> so a class is more appropriate here.
<FromGitter>
<j8r> typically you have structs, and have a class passed around
<FromGitter>
<j8r> like done with `IO`
<FromGitter>
<mwlang> I'll start looking at implementation of some of these core Crystal classes to start getting a better feel for how things are done the crystal-way. I definitely get the feeling I need to unlearn a few Ruby habits.
<FromGitter>
<yxhuvud> Do that, the standard library is very readable (at least if you come from a Ruby background).
<FromGitter>
<j8r> 👍 Symbols are also a good example
<FromGitter>
<mwlang> Ok, I'll start there since it did take me a few tries to get a Hash properly initialized to hold data.
<FromGitter>
<j8r> Enums are a good replacement for some use cases
<FromGitter>
<mwlang> came up with what was basically a hack declaring an empty module Registrable and then "def initialize(options = {} of Symbol => Registrable)" in order to pass an options hash of any kind of object.
<FromGitter>
<mwlang> what is trailing Nil on method definitions doing? e.g. def inspect(io : IO) : Nil
<FromGitter>
<r00ster91> it ensures that the method is really returning `nil`
<FromGitter>
<r00ster91> to avoid mistakes
<FromGitter>
<r00ster91> it also shows up in the docs and makes it very clear to the dev what the method returns
<FromGitter>
<mwlang> are other values possible or is this only used for Nil?
<FromGitter>
<r00ster91> all kinds of values are possible
<FromGitter>
<mwlang> so what happens if my method is declared as returning Int32, but has a bug in it where for some reason it returns Nil or Float64?
<FromGitter>
<Blacksmoke16> Nil is only one that will actually change the return type tho
<FromGitter>
<Blacksmoke16> it wouldnt compile
<FromGitter>
<r00ster91> compile error
<FromGitter>
<mwlang> that's awesome. I really like that side effect.
<FromGitter>
<Blacksmoke16> i.e. if your method is returning Int32 but you have type set to Nil, it will return nil regardless of what value is actually getting returned
<FromGitter>
<Blacksmoke16> any other type restriction would error if the return type does not match
<FromGitter>
<j8r> you can also return an union `: Int32 | Nil` or `: Int32?` (same)
<FromGitter>
<mwlang> I'll have to learn more about Union...I saw that syntax turn up in a couple of compiler errors. I just fixed the bug in my code without knowing what exactly it was.
<FromGitter>
<mwlang> but I gathered I was accidentally producing a Nil result when I really needed always an Int32 or Float64 in my case.
<FromGitter>
<Blacksmoke16> mhm
<FromGitter>
<mwlang> what is "argless constructor" ?
<FromGitter>
<r00ster91> `def initialize`
<FromGitter>
<r00ster91> no arguments
<FromGitter>
<mwlang> ah
<FromGitter>
<Blacksmoke16> which i always misspell :p
<FromGitter>
<j8r> I find it confusing with `def self.new` :/
<FromGitter>
<j8r> (I know the difference)
<FromGitter>
<mwlang> So Crystal has the concept of null pointers? "The only falsey values are nil, false and null pointers (pointers whose memory address is zero)"
<FromGitter>
<Blacksmoke16> if working with unsafe c code, i.e. pointers
<FromGitter>
<mwlang> Thanks to everyone that helped me get past my issue and then gave me most excellent pointers to docs to get started. I just spent time reading through entirety of syntax_and_semantics and reading reference documentation on the various class while inspecting how they were implemented in Crystal.
<FromGitter>
<mwlang> I love how much Crystal reflects the syntax and to some extent idioms of Ruby language, but I also see Crystal goes far beyond with it's ability to tap into C with minimal effort so it's a great bridge (at least for me) to returning to a compilable language without giving up too much of my "Ruby comfort" as I should say.
<FromGitter>
<Blacksmoke16> 💯
<FromGitter>
<mwlang> Whoever dreamed this one up, kudos to the vision and leadership to bring it to life.
<FromGitter>
<mwlang> Does Crystal have a popular hashtag for Twitter?
<FromGitter>
<Fryguy> ❤️
<FromGitter>
<mwlang> Ah well, I tweeted it out and donated. Hope it helps to keep this project going. Will definitely be building some components in Crystal going forward.
<FromGitter>
<mavu> Funny story: ⏎ I ported and expanded a service from nodeJS to Crystal. Was used at a customer site for the first time and a part of the functionality was not working. ⏎ Guess what turned out to be the problem? ⏎ . ⏎ . ... [https://gitter.im/crystal-lang/crystal?at=5cc8597d6a84d76ed81f5f59]
alex```136855585 has quit [Ping timeout: 255 seconds]
waheedi has quit [Quit: waheedi]
issyl0 has joined #crystal-lang
waheedi has joined #crystal-lang
hightower2 has quit [Ping timeout: 250 seconds]
Raimondi has quit [Quit: WeeChat 2.4: ¡Chau!]
hightower2 has joined #crystal-lang
<FromGitter>
<jwoertink> I'm looking to learn how I can include C projects along with my own so when I run a build, it will link and include that project. For example, if I wanted to build a project that includes luaJIT, but without having the user install lua on their own first. Anyone have a link to some docs or a blog post on how to do that?
<z64>
@jwoertink you might check out how https://github.com/jessedoyle/duktape.cr is set up; in short, shard.yml has a `postinstall` directive that invokes `make`. `postinstall` in general opens thing up to do whatever else you'd like done at install time
<FromGitter>
<jwoertink> ah ok. Cool, thanks
<z64>
yw
gangstacat has quit [Ping timeout: 258 seconds]
gangstacat has joined #crystal-lang
<FromGitter>
<bajro17> Hello I have problem with crystal app deploy to Heroku
<FromGitter>
<bajro17> I try deploy kemal web application