Страницы

Поиск по вопросам

суббота, 20 октября 2018 г.

Удаление COM объекта c#

Использую для своего приложения MVC парсер для word документа. Я заметил что после того как парсер отработает, документ остаётся в памяти. Использовал метод :
Marshal.ReleaseComObject(Doc); Marshal.ReleaseComObject(MSWord);
но он не помогает, объект всё ещё висит в памяти. Как удалить объект типа System.__COMObject из памяти?
Проблемные строки:
Word.Application MSWord = new Word.Application();
Word.Document Doc = MSWord.Documents.Open(urlDocMenu, ConfirmConversions: true);
После этих строк появляется объект в памяти и я не знаю как его удалить


Ответ

По-моему, код может быть примерно таким:
var wordApp = new Microsoft.Office.Interop.Word.Application(); wordApp.Visible = true; var doc = wordApp.Documents.Open(urlDocMenu); ... doc.Close(); wordApp.Quit();

Задать маску при вводе c++

Можно ли в c++ создать функцию которая бы задавала маску при вводе?: Н-р номера телефона.
"+7(***)***-**-**"
при вводе уже должна быть выведена маска строки, при нажатии на клавиатуру вместо звездочек должны появляться цифры.


Ответ

Вот такое у меня в винде получилось, работает с MinGW компилятором. Чисто демонстрация, дальше можете развивать как хотите уже.
#include #include #include
int main() { int length = 0; int pospos = 0; int posarrays[10] = {3,4,5,7,8,9,11,12,14,15}; int pos = posarrays[pospos]; char mask[17] = "+7(***)***-**-**"; printf("%s", mask); while(length != 10){ int ch = getch(); if(ch >= '0' && ch <= '9'){ length++; mask[pos] = ch; system("cls"); pospos++; pos = posarrays[pospos]; printf("%s", mask); } } return 0; }

Никак не могу понять смысл использования singleton паттерна

Много наслышан об паттерне программирования "singleton". Вот только никогда на практике не приходилось встречать его в действии (а может и приходилось, но я об этом не догадываюсь). Расскажите, что это такое (по русски, гуглом пользоваться умею, но кроме сухой терминологии и пары non-real-life примеров ничего не находил), как, а главное в каких случаях им можно/нужно пользоваться, ну и желательно пример (на Ruby, если можно).


Ответ

Синглетон - это паттерн, описывающий объект в единственном экземпляре, без возможности создания его копии. Например, у вас имеются настройки для приложения и они должны быть в единственном экземпляре, не допускается создать копию такого объекта, изменить её в одной части приложения, а в другой станется не измененная старая копия. Или установив соединение с базой данных один раз, нужно воспользоваться уже установленным соединением и не создавать его повторно. Вместо базы данных, может быть лог-файл или любой другое хранилище существующее в единственном экземпляре.
Для того, чтобы создать синглетон в Ruby вы должны закрыть возможность создания объекта через new и клонирование объекта (методы clone, dup, _dup). В стандартной библиотеки Ruby уже реализован модуль, подмешав который в собственный класс, вы можете превратить его в синглетон, включив его в класс.
class MyClass include Singleton # ... end
o = MyClass.instance

Округление 0,45 до десятых

Почему команда >? Math.Round(0.45f, 1, MidpointRounding.AwayFromZero) возвращает 0.4 , а команда >? Math.Round(0.45d, 1, MidpointRounding.AwayFromZero) 0.5 ?
Команды выполнены в окне команд Visual Studio 2008, версия .Net Framework 3.5


Ответ

Дело в том, что у 0.45 нет точного представления в двоичном виде. Это приводит к потерям точности даже там, где разработчик ожидает более точного результата.
В вашем случае происходит upcast float-значения 0.45 к double.
0.45f выглядит примерно так
0 01111101 1100 11001100 11001100 110
Это примерно 0.449999988079071044921875
.NET знает что точность float недостаточна, и при преобразовании в строку использует 7 значащих цифр. 0.4499999 88 отображается как 0.45. Поэтому и в отладке, и при выводе на консоль вы увидите 0.45
0.45d - представляется примерно так:
0 0111111 1101 1100 11001100 11001100 11001100 11001100 11001100 11001101
Что примерно равно 0.450000000000000011102230246252. Для double при преобразовании в строку .NET использует 14 значащих цифр. Значение представляется как 0.45000000000000 00 -> 0.45
Ок, теперь вы даете процессору 0.45f и просите его сконвертировать его в double. Процессор берет и добивает нулями:
0 0111111 1101 1100 11001100 11001100 11000000 00000000 00000000 00000000
Что все еще равно 4.49999988079071044921875
С точки зрения процессора - точность не пострадала. Но теперь это double, и при операциях с ним предполагается что он достаточно точен, чтобы при работе с ним как с десятичным числом захватить побольше цифр.
Это больше не "примерно 0.45". Это ведь double. Теперь в нем примерно 14 значащих цифр - значение с точки зрения .NET и процессора превратилось в "примерно 0.449999988079071".
Т.е. в двоичном представлении точность не потерялась, в десятичном - тоже - но полученное число теперь отличается от 0.45d, что приводит к округлению в неожиданном направлении.

Почему работает аналогичный вызов с приведением к decimal:
Math.Round((Decimal)0.45f, 1, MidpointRounding.AwayFromZero) // 0.5
Приведение в decimal происходит через системный вызов метода VarDecFromR4, который при конвертации округляет float до 7 значащих десятичных цифр, делая из 0.449999988079071044921875 красивое 0.4500000
// Round the input to a 7-digit integer. The R4 format has // only 7 digits of precision, and we want to keep garbage digits // out of the Decimal were making.
Собственно, сам код преобразования (пара экранов) в основном посвящен этому округлению с последующим отрезанием незначащих нулей.

Как правильно парсить json C#

Есть json, в котором хранятся точки, из которых, в последствии, строятся определенные 3d объекты, по сути координаты вершин. Особенность в том что лежат они на неравномерной глубине.

Как видно в 31-ом "наборе" точек они лежат сразу после узла "coordinates" а в 32-ом после этого узла они делятся еще на 2 группы, а внутри группы уже искомый набор точек. Задача состоит в том что бы дойти по узлам до элементов составляющих наборы точек (зеленые элементы являются координатами собственно x y), собрать точки принадлежащие одному набору в список, отправить их на обработку и дальше двигаться по json'у. Сложность в том, что там где они делятся на группы (32-ой), надо каждую группу элементов отправлять отдельно, как если бы это была законченная (как в случае с 31-ой, прошлись по 0,1,2 собрали точки внутри отправили пошли дальше), то есть зайти 32-geometry->coordinates->0 все что внутри собрать и отправить затем в 32-geometry->coordinate->1 собрать отправить, затем только дальше. Логично было бы предположить что там где type: MultiLineString можно просто добавить еще один цикл прохода по элементам, но что то мне подсказывает что я неверно рассуждаю. Как решить эту задачу правильно с точки зрения практик парсинга json файлов?
Извините за сумбурное описание, пытался детализировать как мог.
update вот таким образом я пытался добраться до необходимых мне данных, но данные из 32-ой группы сливались в один list и я так и не придумал как ПРАВИЛЬНО, мне их получить. Сейчас я понимаю судя по комментариям и ответам что я подобрался к задаче с принципиально не той стороны.
private void CreateRoads(JSONObject mapData) { int count = 0; foreach (var geo in mapData["features"].list) { count++; var l = new List();
for (int i = 0; i < geo["geometry"]["coordinates"].list.Count; i++) { if (!geo["geometry"]["coordinates"][i][0].IsNumber) {
for (int j = 0; j < geo["geometry"]["coordinates"][i].list.Count; j++) { var c = geo["geometry"]["coordinates"][i][j]; var bm = GM.LatLonToMeters(c[1].f, c[0].f); var pm = new Vector2(bm.x - Rect.center.x, bm.y - Rect.center.y); l.Add(pm.ToVector3xz()); } } else { var c = geo["geometry"]["coordinates"][i]; var bm = GM.LatLonToMeters(c[1].f, c[0].f); var pm = new Vector2(bm.x - Rect.center.x, bm.y - Rect.center.y); l.Add(pm.ToVector3xz()); } }
var m = new GameObject("road_" + count.ToString()).AddComponent(); m.transform.localPosition = new Vector3(m.transform.localPosition.x, m.transform.localPosition.y + 1f, m.transform.localPosition.z); m.transform.parent = this.transform; try { m.Initialize(geo["properties"]["id"].str, this, l, geo["properties"]["kind"].str); } catch (Exception ex) { Debug.Log(ex); } } }
с десериализацией я справился, спасибо @sp7, но как разрулить разные уровни глубины у блоков пока не пойму. Что бы это было универсально, а не хардкодом. Есть мысли на тему прохода в глубину до последнего узла (отличается тем что у него чайлдов видимо) от него вверх на уровень, собираем искомые данные (списки с координатами), отправляем, уровень вверх выходим, смотрим есть ли еще на это же уровне какие то списки, нету снова вверх если вышли до блока coordinates, то переходим к следующему номеру (33,34,35) и тд...вот беда только в том что я не знаю как такой проход в глубину сделать. И гугление не помогло особо =/
var root = JsonConvert.DeserializeObject(www.text); var features = root.roads.features; List coordinates = new List(); for (int i = 0; i < features.Length; i++) { coordinates.Add(features[i].geometry.coordinates); } ConstructRoad(coordinates);


Ответ

Позволю себе высказаться. Как ранее было замечено, для того что бы было удобно работать с Json данными, их нужно как минимум десериализовать в объектный вид.
Поэтому:
1) Если у вас есть эти Json данные в текстовом виде (string) скопируйте их в буфер обмена. Если данных в текстовом виде нет, получите их откуда-то из вне, преобразуйте в строку (как вариант, JObject.Parse().ToString()) и скопируйте в буфер обмена.
2) Создайте пустой С# файл, в нем не должно быть ничего, кроме указания namespace. Курсор ставим внутрь namespace
3) Затем в Visual Studio заходим в меню Edit -> Paste Special -> Paste JSON as Classes
4) Вуаля!!! Visual Studio создала за вас классы, которые представляют указанные Json данные.
5) Теперь когда классы С# готовы, Вы можете ваши Json данные используя JsonSerializer десериализовать в ту объектную модель, что за вас создала студия.
var root = JsonConvert.DeserializeObject(jsonStr);
6) Ну и в завершении, теперь Вы просто можете работать с данными в удобном виде.

Сохранить выделение(:hover) на последнем выделенном элементе

CSS
.can_click { cursor: pointer; }
.can_click:hover { background-color : #1de9b6; }
HTML

{{x.name}}

Как сделать так, чтобы после отвода курсора за пределы таблицы последний элемент, к которому было применено событие :hover, остался выделенным?
Есть какие нибудь простые пути?


Ответ

Вариант без дополнительных директив, с сохранением индекса текущего элемента.
var myApp = angular.module('myApp', []); myApp.controller('myController', function($scope) { $scope.list = [{ name: "Николай" }, { name: "Василий" }, { name: "Сергей" }]; $scope.activeIndex = -1; $scope.mouseenter = function(index) { $scope.activeIndex = index; } }); table { border-collapse: collapse; } .can_click { border: 1px solid #a9a9a9; cursor: pointer; } .active { background-color: #1de9b6; }

{{x.name}}

Битовый размер целочисленного типа

Есть стандартный, шаблонный способ получить размер типов:
template size_t GetSize() { static_assert( false, "Unknown"); return 0; } template <> size_t GetSize< int32_t >() { return 32; } template <> size_t GetSize< char >() { return CHAR_BIT; }
Или нужно вручную написать для всех типов?


Ответ

Достаточно sizeof(x) * CHAR_BIT, потому что sizeof(char) всегда равен 1.

У сервера гаснет физическая консоль, как это отключить?

Я администрирую Linux-серверы (разных дистрибутивов - Ubuntu server, CentOS, Fedora) - физические и виртуальные машины. У большиснтва из них есть неприятная особенность - если в "физическую консоль" (которая не ssh, а в аппаратрном мониторе с аппаратной клавиатурой, реальной или удалённой через iKVM) длительное время ничего не "писать" с клавиатуры, она "гаснет".
В реальности это выглядит так: подходишь к серверу с физическим монитором, цепляешь его - монитор показывает чёрный экран. Цепляешь клавиатуру, нажимаешь any key - монитор оживает и становится видна "физическая консоль" (если речь идёт о машине без иксов - она видна всегда, начиная с загрузки ОС, если иксы есть - то её можно достичь через Ctrl+Alt+F1). Или подключаешься к виртуальной машине по VNC - и то же самое, пока не тронешь клавиатуру - картинки нет.
Речь не идёт о "скринсейвере", это засыпание консоли происходит именно в текстовом режиме.
Как отучить Linux-хосты от такого поведения?


Ответ

Описанное поведение исходит напрямую от ядра Linux, видимо это привет из далёкого прошлого, когда к таким хостам подключались текстовые терминалы с люминофорными устройствами визуализации, которые нужно было беречь от выгорания.
Проверить, через какое время физичекский терминал "погаснет" при отсутсвии пользовательского ввода в него, можно посмотрев на содержимое файла /sys/module/kernel/parameters/consoleblank:
$ cat /sys/module/kernel/parameters/consoleblank 600
Этот файл доступен только на чтение, изменить настройку, перезаписав его, нельзя. Значение в нём - это секунды, то есть в приведённом примере консоль "гаснет" через 10 минут простоя.
Чтобы отключить это поведение глобально и навсегда, следует добавить строку consoleblank=0 к параметрам ядра в конфиге grub и перезагрузить ОС (не забыть про update-grub после редактирования). Например, так:
$ cat /etc/default/grub | grep -v '#'
GRUB_DEFAULT=0 GRUB_HIDDEN_TIMEOUT_QUIET=true GRUB_TIMEOUT=7 GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian` GRUB_CMDLINE_LINUX_DEFAULT="" GRUB_CMDLINE_LINUX="consoleblank=0"
После перезагрузки видим, что параметры ядром считались и приняты:
$ cat /proc/cmdline BOOT_IMAGE=/boot/vmlinuz-4.6.0-040600-generic root=UUID=544c13df-3ff3-47ba-94cc-407e414c6906 ro consoleblank=0
И настройка "засыпания" консоли изменилась:
$ cat /sys/module/kernel/parameters/consoleblank 0
Изменить этот параметр на лету, без перезагрузки, можно с помощью команды setterm, например так: setterm -blank 0 или даже так: setterm -blank 0 -powerdown 0 -powersave off, однако тут есть целых два "НО":
это работает только, если команду setterm вводить в "физическую" консоль (Ctrl+Alt+F1), а при вводе через ssh не работает в Интернете пишут, что поведение setterm меняется от ядра к ядру и от дистрибутива к дистрибутиву, т.е. считать это способ вполне универсальным нельзя

Непонятный код с variadic templates

Есть код, который, используя variadic templates, печатает любое количество входных аргументов в поток:
template void print(Args&& ...args) { char compile_time_buffer[sizeof...(Args)] = { ((std::cout << args <<" "), 0)... }; std::cout<< "
"; }
Совершенно не могу понять, чем инициализируется массив compile_time_buffer. Что скрывается за синтаксисом ((std::cout << args <<" "), 0)? И почему массив char, а в поток корректно выводятся объекты любого типа?


Ответ

В этом выражении
((std::cout << args <<" "), 0)...
используется оператор запятая. Значением выражения является второй операнд после запятой, то есть 0. В результате символьный массив инициализируется нулями. При этом имеется побочный эффект вычисления первого операнда оператора запятая в виде вывода в поток переданных в функцию аргументов.
Чтобы было более наглядно, то просто замените 0, например, на символ 'A'. Ниже показана демонстрационная программа.
#include
template void print( Args && ...args ) { char compile_time_buffer[sizeof...(Args)] = { ( (std::cout << args <<" "), 'A' )... };
std::cout.write( compile_time_buffer, sizeof...(Args) ); }
int main() { print( 1, 2, 3 );
return 0; }
Ее вывод на консоль следующий
1 2 3 AAA
Можно сделать эту программу более интересной. Например,
#include
template void print( Args && ...args ) { char c = 'A'; char compile_time_buffer[sizeof...(Args) + 1] = { ( std::cout << args <<" ", c++ )... };
std::cout << compile_time_buffer << std::endl; }
int main() { print( 1, 2, 3 );
return 0; }
Ее вывод на консоль следующий
1 2 3 ABC
Вот еще один простой пример использования оператора запятая при инициализации переменной
int x = ( std::cout << "Инициализация x. x = ", 10 ); std::cout << x << std::endl;
На консоль будет выведено
Инициализация x. x = 10

Число с фиксированной точностью

Надо вывести число a типа float на экран c точностью не менее n знаков после запятой. Python 3, без использования библиотек.


Ответ

n = 5 a = 1.2345678912345 template = '{:.' + str(n) + 'f}' print(template.format(a))

Нужен ли сейчас underscrore?

Какие возможности underscore вы используете? Например, в нём есть функция each. Зачем она нужна, если теперь есть forEach, map в обычном js? Я так понимаю эта библиотека была актуальна когда не было ES5?


Ответ

Нет не нужен, можно родными средствами языка делать. Интерес к библиотекм постепенно снижается. Вот динамика запросов из гугла:

Сравните сами:
Массивы
_.concat
// Underscore/Lodash var array = [1] var other = _.concat(array, 2, [3], [ [4] ])
console.log(other) // результат: [1, 2, 3, [4]]
// Native var array = [1] var other = array.concat(2, [3], [ [4] ])
console.log(other) // результат: [1, 2, 3, [4]]
_.fill
// Underscore/Lodash var array = [1, 2, 3]
_.fill(array, 'a')
console.log(array) // результат: ['a', 'a', 'a']
_.fill(Array(3), 2) // результат: [2, 2, 2]
_.fill([4, 6, 8, 10], '*', 1, 3) // результат: [4, '*', '*', 10]
// Native var array = [1, 2, 3]
array.fill('a')
console.log(array) // результат: ['a', 'a', 'a']
Array(3).fill(2) // результат: [2, 2, 2]
[4, 6, 8, 10].fill('*', 1, 3) // результат: [4, '*', '*', 10]
_.find
// Underscore/Lodash var users = [{ 'user': 'barney', 'age': 36, 'active': true }, { 'user': 'fred', 'age': 40, 'active': false }, { 'user': 'pebbles', 'age': 1, 'active': true }]
_.find(users, function(o) { return o.age < 40; }) // результат: object for 'barney'
// Native var users = [{ 'user': 'barney', 'age': 36, 'active': true }, { 'user': 'fred', 'age': 40, 'active': false }, { 'user': 'pebbles', 'age': 1, 'active': true }]
users.find(function(o) { return o.age < 40; }) // результат: object for 'barney'
_.findIndex
// Underscore/Lodash var users = [{ 'user': 'barney', 'age': 36, 'active': true }, { 'user': 'fred', 'age': 40, 'active': false }, { 'user': 'pebbles', 'age': 1, 'active': true }]
var index = _.findIndex(users, function(o) { return o.age >= 40; }) console.log(index) // результат: 1
// Native var users = [{ 'user': 'barney', 'age': 36, 'active': true }, { 'user': 'fred', 'age': 40, 'active': false }, { 'user': 'pebbles', 'age': 1, 'active': true }]
var index = users.findIndex(function(o) { return o.age >= 40; }) console.log(index) // результат: 1
_.indexOf
// Underscore/Lodash var array = [2, 9, 9] var result = _.indexOf(array, 2) console.log(result) // результат: 0
// Native var array = [2, 9, 9] var result = array.indexOf(2) console.log(result) // результат: 0
_.join
// Lodash var result = _.join(['one', 'two', 'three'], '--') console.log(result) // результат: 'one--two--three'
// Native var result = ['one', 'two', 'three'].join('--') console.log(result) // результат: 'one--two--three'
_.lastIndexOf
// Underscore/Lodash var array = [2, 9, 9, 4, 3, 6] var result = _.lastIndexOf(array, 9) console.log(result) // результат: 2
// Native var array = [2, 9, 9, 4, 3, 6] var result = array.lastIndexOf(9) console.log(result) // результат: 2
_.reverse
// Lodash var array = [1, 2, 3] console.log(_.reverse(array)) // результат: [3, 2, 1]
// Native var array = [1, 2, 3] console.log(array.reverse()) // результат: [3, 2, 1]
Коллекции
_.each
// Underscore/Lodash _.each([1, 2, 3], function(value, index) { console.log(value) }) // результат: 1 2 3
// Native [1, 2, 3].forEach(function(value, index) { console.log(value) }) // результат: 1 2 3
_.every
// Underscore/Lodash function isLargerThanTen(element, index, array) { return element >= 10 } var array = [10, 20, 30] var result = _.every(array, isLargerThanTen) console.log(result) // результат: true
// Native function isLargerThanTen(element, index, array) { return element >= 10 }
var array = [10, 20, 30] var result = array.every(isLargerThanTen) console.log(result) // результат: true
_.filter
// Underscore/Lodash function isBigEnough(value) { return value >= 10 } var array = [12, 5, 8, 130, 44] var filtered = _.filter(array, isBigEnough) console.log(filtered) // результат: [12, 130, 44]
// Native function isBigEnough(value) { return value >= 10 } var array = [12, 5, 8, 130, 44] var filtered = array.filter(isBigEnough) console.log(filtered) // результат: [12, 130, 44]
_.includes
var array = [1, 2, 3] // Underscore/Lodash - also called with _.contains _.includes(array, 1) // результат: true
// Native var array = [1, 2, 3] array.includes(1) // результат: true
// Native (only works with flat array values, no complex objects) var array = [1, 2, 3] array.indexOf(1) > -1 // результат: true
_.map
// Underscore/Lodash var array1 = [1, 2, 3] var array2 = _.map(array1, function(value, index) { return value * 2 }) console.log(array2) // результат: [2, 4, 6]
// Native var array1 = [1, 2, 3] var array2 = array1.map(function(value, index) { return value * 2 }) console.log(array2) // результат: [2, 4, 6]
_.pluck
// Underscore/Lodash var array1 = [{ name: "Alice" }, { name: "Bob" }, { name: "Jeremy" }] var names = _.pluck(array1, "name") console.log(names) // результат: ["Alice", "Bob", "Jeremy"]
// Native var array1 = [{ name: "Alice" }, { name: "Bob" }, { name: "Jeremy" }] var names = array1.map(function(x) { return x.name }) console.log(names) // результат: ["Alice", "Bob", "Jeremy"]
_.reduce
// Underscore/Lodash var array = [0, 1, 2, 3, 4] var result = _.reduce(array, function(previousValue, currentValue, currentIndex, array) { return previousValue + currentValue }) console.log(result) // результат: 10
// Native var array = [0, 1, 2, 3, 4] var result = array.reduce(function(previousValue, currentValue, currentIndex, array) { return previousValue + currentValue }) console.log(result) // результат: 10
_.reduceRight
// Underscore/Lodash var array = [0, 1, 2, 3, 4] var result = _.reduceRight(array, function(previousValue, currentValue, currentIndex, array) { return previousValue - currentValue }) console.log(result) // результат: -2
// Native var array = [0, 1, 2, 3, 4] var result = array.reduceRight(function(previousValue, currentValue, currentIndex, array) { return previousValue - currentValue }) console.log(result) // результат: -2
_.size
// Underscore/Lodash var result = _.size({ one: 1, two: 2, three: 3 }) console.log(result) // результат: 3
// Native var result2 = Object.keys({ one: 1, two: 2, three: 3 }).length console.log(result2) // результат: 3
_.some
// Underscore/Lodash function isLargerThanTen(element, index, array) { return element >= 10 } var array = [10, 9, 8] var result = _.some(array, isLargerThanTen) console.log(result) // результат: true
// Native function isLargerThanTen(element, index, array) { return element >= 10 }
var array = [10, 9, 8] var result = array.some(isLargerThanTen) console.log(result) // результат: true
Функции
_.after
var notes = ['profile', 'settings'] // Underscore/Lodash var renderNotes = _.after(notes.length, render) notes.forEach(function(note) { console.log(note) renderNotes() })
// Native notes.forEach(function(note, index) { console.log(note) if (notes.length === (index + 1)) { render() } })
Язык
_.isNaN
// Underscore/Lodash console.log(_.isNaN(NaN)) // результат: true
// Native console.log(isNaN(NaN)) // результат: true
// ES6 console.log(Number.isNaN(NaN)) // результат: true
Объект
_.assign
// Underscore: _.extendOwn // Lodash function Foo() { this.c = 3; }
function Bar() { this.e = 5; } Foo.prototype.d = 4; Bar.prototype.f = 6; var result = _.assign(new Foo, new Bar); console.log(result); // результат: { 'c': 3, 'e': 5 }
// Native function Foo() { this.c = 3; }
function Bar() { this.e = 5; } Foo.prototype.d = 4; Bar.prototype.f = 6; var result = Object.assign(new Foo, new Bar); console.log(result); // результат: { 'c': 3, 'e': 5 }
_.keys
// Underscore/Lodash var result = _.keys({ one: 1, two: 2, three: 3 }) console.log(result) // результат: ["one", "two", "three"]
// Native var result2 = Object.keys({ one: 1, two: 2, three: 3 }) console.log(result2) // результат: ["one", "two", "three"]
Строка
_.repeat
// Lodash var result = _.repeat('abc', 2) // результат: 'abcabc'
// Native var result = 'abc'.repeat(2) console.log(result) // результат: 'abcabc'
_.toLower
// Lodash var result = _.toLower('FOOBAR') console.log(result) // результат: 'foobar'
// Native var result = 'FOOBAR'.toLowerCase() console.log(result) // результат: 'foobar'
_.toUpper
// Lodash var result = _.toUpper('foobar') console.log(result) // результат: 'FOOBAR'
// Native var result = 'foobar'.toUpperCase() console.log(result) // результат: 'FOOBAR'
_.trim
// Lodash var result = _.trim(' abc ') console.log(result) // результат: 'abc'
// Native var result = ' abc '.trim() console.log(result) // результат: 'abc'
Ссылки
Оригинал Mozilla Developer Network Underscore.js Lodash.js You - Dont - Need - jQuery

Garbage Collector в неуправляемом коде

Если я создам массив байт, например, и передам указатель на него в неуправляемый код, что с этим массивом будет делать Garbage Collector?


Ответ

В C# это зависит от того, как вы передаёте массив в неуправляемый код.
Обычно сборщик мусора имеет право в любой момент переместить любой управляемый объект в памяти. Чтобы этого не произошло, вы должны прикрепить объект, чтобы сборщик мусора не пытался его переместить. Для этого существует несколько методов, например, ключевое слово fixed
unsafe void F() { int[] data = { 1, 2, 3 }; fixed (int* p = &data[0]) { // тут у вас есть указатель, можно передавать его в нативный код } }
Понятно, данные будут закреплены лишь в области действия fixed, поэтому если вы запомните указатель в переменной и воспользуетесь им по окончанию блока fixed, ваша память может быть перемещена или собрана сборщиком мусора, и вы на пути к undefined behaviour, как в старые недобрые времена. Ответственность за корректность поведения unsafe-кода лежит на вас и только на вас.
Для ручной работы с адресами вам могут понадобиться IntPtr (для представления указателя в безопасном коде), GCHandle (для низкоуровневого обращения с объектами с точки зрения сборщика мусора) и особенно Marshal для ручного преобразования между нативными и управляемыми объектами.

Другой метод передавать нативной функции массив — вызов через P/Invoke. В этом случае то же самое делает за вас маршаллер. Вам придётся выписать правильную сигнатуру P/Invoke, наподобие такой:
void F( [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] long[] ar, int size);
(сигнатуры можно составить самому, вдумчиво почитав документацию, или подсмотреть сигнатуры для популярных функций WinAPI на http://pinvoke.net). Маршаллинг не может проверить правильность сигнатуры, поэтому если вы ошибётесь, последствия, думаю, понятны.

Пакет Блога для Laravel 5.3

Подскажите готовый пакет блога для интеграции в работающий проект. Все что я видел до этого мешают работе основного проекта либо сложно управляются.
Если таких пакетов нет возможно у вас есть идеи как сделать блог в короткие сроки с использованием посторонних пакетов. Например уже думали над тем чтобы поднять блог по готовому пакету как отдельный апликейшен с доступом в админку а за данными просто ходить в другую базу но это какое-то извращение.


Ответ

Так как другие пакеты не давали нужного функционала из коробки был выбран canvas.toddaustin.io после нескольких часов танцов с бубном все завелось но пакет сорит своими файлами и перезаписывает своиже конфиги что дико мешает. Но что-то с этим придумаем)

Как максимальную ширину изображения ограничить реальной шириной изображения?

На странице вставлена картинка:
photo
img { display: block; width: 100%; max-width: 500px; }
Максимальная ширина картинки - 500px. Если у нас ширина родителя меньше 500px, то картинка занимает 100% ширины родителя.
Но может быть так, что реальная ширина картинки меньше, чем 500px.
Как ограничить максимальную ширину картинки, если она больше 500px, и не растягивать картинку до 500px, если картинка меньшей ширины?


Ответ

Надо ограничивать наоборот: сколько надо, но не больше 100%:
img { display: block; width: auto; height: auto; max-width: 100%; } photo photo